Embryos are largely understudied in conservation physiology

Patrice Pottier

latest update: 05 August 2025

Load relevant packages

pacman::p_load(tidyverse,
               ggstream,
               flextable,
               bibliometrix,
               bib2df,
               circlize,
               patchwork) # p_load() will install packages if they are not installed already
set.seed(123)

Import data

# Import survey data
raw_data <- read_csv("Data/extracted_data_cons_phys_life_stages.csv")

# Remove spaces in column names
colnames(raw_data) <- gsub(" ", "_", colnames(raw_data))

Data cleaning

# Fix some typos, titles swapped with the reference information, or missing publication years
data <- raw_data
data$Short_reference[data$Short_reference == "Illing_et_al_2029"] <- "Illing_et_al_2020"
data$Short_reference[data$Short_reference == "Shartau_et_al_2002"] <- "Shartau_et_al_2016"
data$Short_reference[data$Short_reference == "Abdelqader_and_Al-Fataftah"] <- "Abdelqader_and_Al-Fataftah_2014"
data$Short_reference[data$Short_reference == "Wiedenova_et_al_"] <- "Wiedenova_et_al_2018"
data$Short_reference[data$Short_reference == "Radugina_and_Grigoryan"] <- "Radugina_and_Grigoryan_2018"

data$Short_reference[data$Short_reference == "Acute thermal stress and endotoxin exposure modulate metabolism and immunity in marine mussels (Perna canaliculus)"] <- "Muznebin_et_al_2022"
data$Title[data$Short_reference == "Muznebin_et_al_2022"] <- "Acute thermal stress and endotoxin exposure modulate metabolism and immunity in marine mussels (Perna canaliculus)"
data$Short_reference[data$Short_reference == "Heat stress is associated with disruption of ion balance in the migratory locust, Locusta migratoria"] <- "O'Sullivan_et_al_2017"
data$Title[data$Short_reference == "O'Sullivan_et_al_2017"] <- "Heat stress is associated with disruption of ion balance in the migratory locust, Locusta migratoria"

data <- data %>% filter(Title != "Physiological correlates of symbiont migration during bleaching of two octocoral species")
data$Title[data$Title == "Physiological correlates of symbiont migration during bleaching of two octocoral species  Katharina"] <- "Physiological correlates of symbiont migration during bleaching of two octocoral species"
  
# Remove duplicates 
data %>% group_by(Title) %>% summarise(n=n()) %>% filter(n>1) # Check if any title is duplicated
## # A tibble: 2 × 2
##   Title                                                                        n
##   <chr>                                                                    <int>
## 1 Control of lung ventilation following overwintering conditions in bullf…     2
## 2 The importance of thermal history: costs and benefits of heat exposure …     2
data <- data %>% distinct(Title, .keep_all = TRUE) # Remove duplicate

# Create a column for publication year
data <- data %>%
  mutate(Publication_year = as.integer(str_extract(Short_reference, "\\d{4}")))

# Rename columns
data <- rename(data, 
               Life_stage_exposed = Life_stage_exposed_to_the_stressor,
               Life_stage_tested = Life_stage_of_the_animals_when_traits_were_measured)

# View Trait categories
#View(data.frame(table(raw_data$Trait_category)))

# Delete and rename some observations for trait categories
data <- data %>% 
  filter(Trait_category != "Biomechanics",
         Trait_category != "micro RNA expression") %>% 
  mutate(Trait_category = case_when(
      Trait_category == "Resting membrane potential" ~ "Energetics and metabolism",
      Trait_category == "DNA damage" ~ "Immune function and stress physiology",
      Trait_category == "Energetics and metabolism, Haematology" ~ "Energetics and metabolism, Cardiovascular physiology",
      Trait_category == "Energetics and metabolism, Osmoregulation, FLIGHT ACTIVITY, ALLOMETRIC MEASURES, Cuticular hydrocarbons,AKH-related gene expression variations" ~ "Energetics and metabolism, Osmoregulation",
      Trait_category == "Environmental tolerance and preference, Cardiovascular physiology, Respiratory physiology" ~ "Environmental tolerance and preference, Cardiovascular physiology, Energetics and metabolism",
      Trait_category == "Environmental tolerance and preference, Clearance (feeding) rate" ~ "Environmental tolerance and preference",
      Trait_category == "Environmental tolerance and preference, Development, Acclimation" ~ "Environmental tolerance and preference, Development",
      Trait_category == "Environmental tolerance and preference, Development, Behavior" ~ "Environmental tolerance and preference, Development",
      Trait_category == "Environmental tolerance and preference, Development, Embryo physiology" ~ "Environmental tolerance and preference, Development",
      Trait_category == "Environmental tolerance and preference, Development, thyroid function" ~ "Environmental tolerance and preference, Development, Other",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Behavior" ~ "Environmental tolerance and preference, Energetics and metabolism",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Behavior and physiology" ~ "Environmental tolerance and preference, Energetics and metabolism",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, condition factor, relative intestinal mass, and hepatosomatic index" ~ "Environmental tolerance and preference, Energetics and metabolism, Development",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Immune function and stress physiology, Behavioral responses" ~ "Environmental tolerance and preference, Energetics and metabolism, Immune function and stress physiology",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Immune function and stress physiology, Development, Behavior" ~ "Environmental tolerance and preference, Energetics and metabolism, Immune function and stress physiology, Development",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Morphology and Behavior" ~ "Environmental tolerance and preference, Energetics and metabolism",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Osmoregulation, Behavior" ~ "Environmental tolerance and preference, Energetics and metabolism, Osmoregulation",
      Trait_category == "Environmental tolerance and preference, Energetics and metabolism, Performance" ~ "Environmental tolerance and preference, Energetics and metabolism",
      Trait_category == "Environmental tolerance and preference, gut microbiome" ~ "Environmental tolerance and preference, Other",
      Trait_category == "Environmental tolerance and preference, Immune function and stress physiology, thyroid hormones" ~ "Environmental tolerance and preference, Immune function and stress physiology, Other",
      Trait_category == "Environmental tolerance and preference, Neurophysiology" ~ "Environmental tolerance and preference, Other",
      Trait_category == "Environmental tolerance and preference, Performance" ~ "Environmental tolerance and preference",
      Trait_category == "Environmental tolerance and preference, photochemical parameters/symbiont density" ~ "Environmental tolerance and preference, Other",
      Trait_category == "Environmental tolerance and preference, Physiology and behavior" ~ "Environmental tolerance and preference",
      Trait_category == "Environmental tolerance and preference, Reproduction, lifespan" ~ "Environmental tolerance and preference, Reproduction, Development",
      Trait_category == "gene expression of 'energy regulation' pathways" ~ "Energetics and metabolism",
      Trait_category == "Immune function and stress physiology, Development, gene expression" ~ "Immune function and stress physiology, Development",
      Trait_category == "mitochondrial membrane potential; proton leak; ratio of moles of ADP consumed per mole of oxygen" ~ "Energetics and metabolism",
      Trait_category == "Osmoregulation, Hydroregulation" ~ "Osmoregulation",    
      Trait_category == "Osmoregulation, Immune function and stress physiology, behavior" ~ "Osmoregulation, Immune function and stress physiology",    
      Trait_category == "Osmoregulation, Performance" ~ "Osmoregulation",  
      Trait_category == "Osmoregulation, Sensory physiology" ~ "Osmoregulation, Other",  
      Trait_category == "Resting membrane potential" ~ "Environmental tolerance and preference",  
      Trait_category == "Reproduction, Development, longevity" ~ "Reproduction, Development, Environmental tolerance and preference",
      Trait_category == "Reproduction, Development, mortality" ~ "Reproduction, Development, Environmental tolerance and preference",
      Trait_category == "Energetics and metabolism, Immune function and stress physiology, membrane potential" ~ "Energetics and metabolism, Immune function and stress physiology",
      Trait_category == "Environmental tolerance and preference, membrane potential" ~ "Environmental tolerance and preference",
      Trait_category == "Osmoregulation, membrane potential" ~ "Osmoregulation, Energetics and metabolism",
      Trait_category == "Energetics and metabolism, membrane potential" ~ "Energetics and metabolism", 
      TRUE ~ Trait_category
    ))

# Check unique categories
 data %>%
  pull(Trait_category) %>%       
  strsplit(", ") %>%                    
  unlist() %>%                           
  unique() # All good
## [1] "Osmoregulation"                        
## [2] "Immune function and stress physiology" 
## [3] "Energetics and metabolism"             
## [4] "Cardiovascular physiology"             
## [5] "Development"                           
## [6] "Environmental tolerance and preference"
## [7] "Reproduction"                          
## [8] "Other"
# View stressor categories
#View(data.frame(table(data$Climate_change_stressor)))

# Delete and rename some observations for environmental stressors
data <- data %>% 
  filter(Climate_change_stressor != "pressure exposure",
         Climate_change_stressor != "Interaction with non-climatic stressor") %>% 
  mutate(Climate_change_stressor = case_when(
      Climate_change_stressor == "Acidification" ~ "pH",
      Climate_change_stressor == "altitude" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Calcium content" ~ "pH",
      Climate_change_stressor == "CO2" ~ "Oâ‚‚/COâ‚‚", 
      Climate_change_stressor == "diet" ~ "Other", 
      Climate_change_stressor == "Diet" ~ "Other",
      Climate_change_stressor == "diet and water" ~ "Other, Humidity/Water availability", 
      Climate_change_stressor == "Humidity" ~ "Humidity/Water availability",
      Climate_change_stressor == "Hypercapnia" ~ "Oâ‚‚/COâ‚‚", 
      Climate_change_stressor == "Interaction with non-climatic stressor, water restriction" ~ "Interaction with non-climatic stressor, Humidity/Water availability",
      Climate_change_stressor == "osmolality" ~ "Salinity", 
      Climate_change_stressor == "Oxygen, acidification" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "Oxygen, Acidification" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "Oxygen, altitude" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Oxygen, carbon dioxide" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Oxygen" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Oxygen, CO2" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Oxygen, Humidity" ~ "Oâ‚‚/COâ‚‚, Humidity/Water availability",
      Climate_change_stressor == "Oxygen, pH, Interaction with non-climatic stressor" ~ "Oâ‚‚/COâ‚‚, Interaction with non-climatic stressor, pH",
      Climate_change_stressor == "Oxygen, hypercapnia" ~ "Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Oxygen, Interaction with non-climatic stressor" ~ "Oâ‚‚/COâ‚‚, Interaction with non-climatic stressor",
      Climate_change_stressor == "Oxygen, light" ~ "Oâ‚‚/COâ‚‚, Interaction with non-climatic stressor",
      Climate_change_stressor == "Oxygen, pH" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "Oxygen, pH, acidification" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "Oxygen, pH, carbon dioxide" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "Oxygen, Salinity" ~ "Oâ‚‚/COâ‚‚, Salinity",
      Climate_change_stressor == "pH, acidification" ~ "pH",
      Climate_change_stressor == "pH, Acidification" ~ "pH",
      Climate_change_stressor == "pH, Aluminum toxicity" ~ "pH, Interaction with non-climatic stressor",
      Climate_change_stressor == "pH, Hypercapnia" ~ "Oâ‚‚/COâ‚‚, pH",
      Climate_change_stressor == "pH, Salinity, CO2" ~ "Oâ‚‚/COâ‚‚, pH, Salinity",
      Climate_change_stressor == "pH, salt and ammonia" ~ "pH, Salinity, Interaction with non-climatic stressor",
      Climate_change_stressor == "precipitation: rainy vs dry" ~ "Humidity/Water availability",
      Climate_change_stressor == "Salinity, dessication" ~ "Salinity, Humidity/Water availability",
      Climate_change_stressor == "Temperature, acidification" ~ "Temperature, pH",
      Climate_change_stressor == "Temperature, Acidification" ~ "Temperature, pH",
      Climate_change_stressor == "Temperature, Artificial light" ~ "Temperature, Interaction with non-climatic stressor",
      Climate_change_stressor == "Temperature, Carbon Dioxide" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, CO2" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, dehydration" ~ "Temperature, Humidity/Water availability",
      Climate_change_stressor == "Temperature, desiccation" ~ "Temperature, Humidity/Water availability",
      Climate_change_stressor == "Temperature, Diet" ~ "Temperature, Other",
      Climate_change_stressor == "Temperature, food restriction" ~ "Temperature, Other",
      Climate_change_stressor == "Temperature, food scarcity" ~ "Temperature, Other",
      Climate_change_stressor == "Temperature, Humidity" ~ "Temperature, Humidity/Water availability",
      Climate_change_stressor == "Temperature, limited food availability" ~ "Temperature, Other",
      Climate_change_stressor == "Temperature, low water volume" ~ "Temperature, Humidity/Water availability",
      Climate_change_stressor == "Temperature, Oxygen" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, CO2" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, Humidity" ~ "Temperature, Humidity/Water availability, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, hypercapnia" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, Hypercapnia" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, Interaction with non-climatic stressor" ~ "Temperature, Oâ‚‚/COâ‚‚, Interaction with non-climatic stressor",
      Climate_change_stressor == "Temperature, Oxygen, PCO2" ~ "Temperature, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, pH" ~ "Temperature, pH, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, Oxygen, Salinity" ~ "Temperature, Salinity, Oâ‚‚/COâ‚‚",
      Climate_change_stressor == "Temperature, pH, acidification" ~ "Temperature, pH",
      Climate_change_stressor == "Temperature, photoperiod" ~ "Temperature, Interaction with non-climatic stressor",
      Climate_change_stressor == "Temperature, UV" ~ "Temperature, Other", 
      Climate_change_stressor == "Temperature, UV-B radiation" ~ "Temperature, Other", 
      Climate_change_stressor == "Temperature, UV radiation" ~ "Temperature, Other", 
      Climate_change_stressor == "Temperature, water restriction" ~ "Temperature, Humidity/Water availability",
      Climate_change_stressor == "Temperature, wave action" ~ "Temperature, Interaction with non-climatic stressor",
      Climate_change_stressor == "Ultraviolet B radiation (UV-B)" ~ "Other", 
      Climate_change_stressor == "UV-B" ~ "Other", 
      Climate_change_stressor == "UV" ~ "Other", 
      Climate_change_stressor == "UV-B exposure" ~ "Other", 
      Climate_change_stressor == "UV radiation" ~ "Other", 
      Climate_change_stressor == "water" ~ "Humidity/Water availability",
      Climate_change_stressor == "Water availability" ~ "Humidity/Water availability",
      Climate_change_stressor == "water deprivation" ~ "Humidity/Water availability",
      Climate_change_stressor == "water restriction" ~ "Humidity/Water availability",
      TRUE ~ Climate_change_stressor
    ))
# Diet and UV radiation were pooled together as "Other" because they were rare

# Check unique categories
 data %>%
  pull(Climate_change_stressor) %>%       
  strsplit(", ") %>%                    
  unlist() %>%                           
  unique() # All good
## [1] "Humidity/Water availability"           
## [2] "Oâ‚‚/COâ‚‚"                                
## [3] "Other"                                 
## [4] "Temperature"                           
## [5] "Salinity"                              
## [6] "Interaction with non-climatic stressor"
## [7] "pH"
#######################
 
# View life stage exposed categories
#View(data.frame(table(data$Life_stage_exposed)))

# Delete and rename some observations. Each of these were checked manually and resolved.
data <- data %>% 
  mutate(Life_stage_exposed = case_when(
      Life_stage_exposed == "adults" ~ "Adults",
      Life_stage_exposed == "Adults, Unclear" ~ "Unclear",
      Life_stage_exposed == "Embryos, gametes and embryos." ~ "Embryos",
      Life_stage_exposed == "Embryos, Larvae or juveniles, Adults, 7 generations exposed to 2 different temps" ~ "Mix (before and after hatching)",
      Life_stage_exposed == "Embryos, Larvae or juveniles, Adults, Mix (before and after hatching)" ~ "Mix (before and after hatching)",
      Life_stage_exposed == "Embryos, maybe also juveniles. It's unclear when the temperature treatment ends." ~ "Embryos, Adults",
      Life_stage_exposed == "exposure was at a single time point, but performed on a mixture of juveniles and adults for the one experiment" ~ "Mix (strictly after hatching)",
      Life_stage_exposed == "it is one exposure, occurring at a single time point, but some of the individuals were adult and some were juvenile." ~ "Mix (strictly after hatching)",
      Life_stage_exposed == "Larvae or juveniles, adults" ~ "Larvae or juveniles, Adults",
      Life_stage_exposed == "Larvae or juveniles, Age-0 (could be juveniles or adults)" ~ "Larvae or juveniles", # all species are not sexually mature at this age
      Life_stage_exposed == "Larvae or juveniles, exposure was performed on larvae only but for 13 consecutive generations" ~ "Larvae or juveniles",
      Life_stage_exposed == "Subadult" ~ "Larvae or juveniles", # Sub adults can be considered juveniles
      Life_stage_exposed == "Unclear, 4 month old male rats" ~ "Adults", # They are sexually mature at this age
      Life_stage_exposed == "Unclear, Either juveniles, adults, or a mixture of both stages. Can't easily determine it." ~ "Unclear",
      Life_stage_exposed == "Unclear, I can infer its post-hatching, but cannot say with certainty whether they're juveniles or adults." ~ "Unclear",
      Life_stage_exposed == "Unclear, I think it is either juvenile or adult but they don't specify" ~ "Unclear",
      Life_stage_exposed == "Unclear, probably juveniles or adults" ~ "Unclear",
      Life_stage_exposed == "Adults, Colonial organisms. Included gravid reproductive zooids but also incomplete zooids" ~ "Mix (strictly after hatching)",
      TRUE ~ Life_stage_exposed
    ))

 data %>%
  pull(Life_stage_exposed) %>%       
  strsplit(", ") %>%                    
  unlist() %>%                           
  unique() # All good. 
## [1] "Adults"                          "Embryos"                        
## [3] "Larvae or juveniles"             "Mix (before and after hatching)"
## [5] "Unclear"                         "Mix (strictly after hatching)"
#######################
 
# View life stage tested categories
#View(data.frame(table(data$Life_stage_tested)))
 
# Delete and rename some observations for life stages
data <- data %>% 
  mutate(Life_stage_tested = case_when(
      Life_stage_tested == "adults" ~ "Adults",
      Life_stage_tested == "Adults, Colonial organisms. Included gravid reproductive zooids but also incomplete zooids" ~ "Adults, Larvae or juveniles",
      Life_stage_tested == "Adults, Progeny of these adults that were exposed to diff temperature as embryos (F2)" ~ "Adults, Larvae or juveniles",
      Life_stage_tested == "Adults, Unclear" ~ "Unclear",
      Life_stage_tested == "Adults, unfertilized eggs" ~ "Adults",
      Life_stage_tested == "analysis is on homogenates generated from multiple individuals likely spanning all life-stages." ~ "Adults, Larvae or juveniles",
      Life_stage_tested == "Embryos, Larvae and juveniles" ~ "Embryos, Larvae or juveniles",
      Life_stage_tested == "exposure was at a single time point, but performed on a mixture of juveniles and adults for the one experiment" ~ "Adults, Larvae or juveniles",
      Life_stage_tested == "it is one experiment, occurring at a single time point, but some of the individuals were adult and some were juvenile." ~ "Adults, Larvae or juveniles",
      Life_stage_tested == "Larvae or juveniles, adults" ~ "Larvae or juveniles, Adults", 
      Life_stage_tested == "Larvae or juveniles, Age-0 (could be juveniles or adults)" ~ "Larvae or juveniles",
      Life_stage_tested == "Subadult" ~ "Larvae or juveniles", 
      Life_stage_tested == "Unclear, 4 months old male rats" ~ "Adults", 
      Life_stage_tested == "Unclear, Either juveniles, adults, or a mixture of both stages. Can't easily determine it." ~ "Unclear",
      Life_stage_tested == "Unclear, I can infer its post-hatching, but cannot say with certainty whether they're juveniles or adults." ~ "Unclear",
      Life_stage_tested == "Unclear, I think it is either juvenile or adult but they don't specify" ~ "Unclear",
      Life_stage_tested == "Unclear, probably juvenile or adults" ~ "Unclear",
      TRUE ~ Life_stage_tested
    ))

 data %>%
  pull(Life_stage_tested) %>%       
  strsplit(", ") %>%                    
  unlist() %>%                           
  unique() # All good.   
## [1] "Adults"              "Larvae or juveniles" "Embryos"            
## [4] "Unclear"

Save processed data and citation information

# Read files with bibliographic information prior to screening
bib <- read_csv("Bibliographic_searches/all_bibliographic_records.csv")
bib <- bib %>% rename(DOI = doi)

# Left join the files to only keep the included studies
included_studies <- left_join(data, bib, by="DOI")

included_studies <- included_studies %>% 
  dplyr::select(title, authors, journal, DOI, abstract, year, volume, issue, pages)

# Save bibliographic file
write_csv(included_studies, file = "Bibliographic_searches/all_included_studies.csv")

# Save processed data 
data <- data %>% 
  dplyr::select(Short_reference, Publication_year, Title, DOI, Journal, Taxonomic_group, Climate_change_stressor, Life_stage_exposed, Life_stage_tested, Trait_category, Trait_details, Additional_comments)

write_csv(data, file = "Data/cleaned_data.csv")

Overall data summary

The numbers below represent the number of studies from different journals, trait categories, climatic stressors, taxa, and life stages (exposed to the climatic stressor, or assessed for physiological traits). Note that because some studies have investigated multiple traits, stressors, taxa, and life stages, the numbers do not add to the total number of studies (n = 1245).

Journals

# Number of studies per journal
journal_summary <- data %>% 
  pull(Journal) %>% 
  table() %>% 
  as.data.frame() %>% 
  rename(`Journal` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(percentage)

flextable(journal_summary) %>%
  autofit() %>%
  set_caption("Journals") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")  # 181 from Cons Phys, 562 from JEB, 533 from JTB.
Journals

Journal

n

percentage

Conservation Physiology

181

14.18495

Journal of Thermal Biology

533

41.77116

Journal of Experimental Biology

562

44.04389

# Total number of studies
n_distinct(data$DOI) # 1276 studies
## [1] 1276

Trait categories

# Traits
trait_summary <- data %>%
  pull(Trait_category) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Trait category` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(desc(percentage))

flextable(trait_summary) %>%
  autofit() %>%
  set_caption("Trait categories") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Trait categories

Trait category

n

percentage

Environmental tolerance and preference

727

30.7659755

Energetics and metabolism

574

24.2911553

Development

380

16.0812526

Immune function and stress physiology

246

10.4104951

Osmoregulation

170

7.1942446

Reproduction

138

5.8400339

Cardiovascular physiology

122

5.1629285

Other

6

0.2539145

Taxonomic groups

# Taxa
taxa_summary <- data %>%
  pull(Taxonomic_group) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Taxonomic group` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(desc(percentage))

flextable(taxa_summary) %>%
  autofit() %>%
  set_caption("Taxonomic groups") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Taxonomic groups

Taxonomic group

n

percentage

Fish

398

31.069477

Insect

238

18.579235

Other invertebrate

226

17.642467

Mammal

137

10.694770

Bird

112

8.743169

Reptile

100

7.806401

Amphibian

70

5.464481

Climate change stressors

# Stressors
stressor_summary <- data %>%
  pull(Climate_change_stressor) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Climatic stressor` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(desc(percentage))

flextable(stressor_summary) %>%
  autofit() %>%
  set_caption("Climate change stressors") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Climate change stressors

Climatic stressor

n

percentage

Temperature

1,041

65.0625

Oâ‚‚/COâ‚‚

194

12.1250

Interaction with non-climatic stressor

138

8.6250

pH

83

5.1875

Salinity

68

4.2500

Humidity/Water availability

60

3.7500

Other

16

1.0000

# After removing studies from the Journal of Thermal Biology (which is largely focusing on temperature)
stressor_summary_jtb <- data %>%
  filter(Journal != "Journal of Thermal Biology") %>% 
  pull(Climate_change_stressor) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Climate_stressor` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(percentage)

flextable(stressor_summary_jtb) %>%
  autofit() %>%
  set_caption("Climate change stressors") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Climate change stressors

Climate_stressor

n

percentage

Other

15

1.582278

Humidity/Water availability

50

5.274262

Salinity

58

6.118143

Interaction with non-climatic stressor

59

6.223629

pH

82

8.649789

Oâ‚‚/COâ‚‚

172

18.143460

Temperature

512

54.008439

Life stage exposed to the stressor

# Life stage exposed to the climatic stressor
ls_exposed_summary <- data %>%
  pull(Life_stage_exposed) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Life stage exposed` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(desc(percentage))

flextable(ls_exposed_summary) %>%
  autofit() %>%
  set_caption("Life stages exposed to the stressor") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages exposed to the stressor

Life stage exposed

n

percentage

Adults

690

49.462366

Larvae or juveniles

402

28.817204

Embryos

131

9.390681

Unclear

82

5.878136

Mix (before and after hatching)

59

4.229391

Mix (strictly after hatching)

31

2.222222

Life stage assessed for physiological traits

# Life stage tested for physiological traits
ls_tested_summary <- data %>%
  pull(Life_stage_tested) %>%
  strsplit(", ") %>%
  unlist() %>%
  table() %>%
  as.data.frame() %>%
  rename(`Life stage tested` = ".", n = "Freq") %>%
  mutate(percentage = (n / sum(n))*100) %>%
  arrange(desc(percentage))

flextable(ls_tested_summary) %>%
  autofit() %>%
  set_caption("Life stages assessed for physiological traits") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages assessed for physiological traits

Life stage tested

n

percentage

Adults

788

52.393617

Larvae or juveniles

513

34.109043

Embryos

120

7.978723

Unclear

83

5.518617

Data summary by life stage (exposed to climatic stressors)

Here, data summaries are generated separately for each life stage. In this study, we differentiated the life stages exposed to climatic stressors (presented here), to those assessed for physiological stressors (presented further below), as these sometimes differ, especially in the context of longitudinal studies.

Helper function

# Helper function for splitting + unnesting life stages
split_and_summarise <- function(data, group_var) {
  life_stage_order <- c("Unclear", "Mix (strictly after hatching)", "Mix (before and after hatching)", "Embryos", "Larvae or juveniles", "Adults")
  data %>%
    mutate(across(all_of(c("Life_stage_exposed", group_var)), ~ strsplit(as.character(.), ", "))) %>%
    unnest(Life_stage_exposed) %>%
    unnest(all_of(group_var)) %>%
    mutate(Life_stage_exposed = factor(Life_stage_exposed, levels = life_stage_order)) %>%
    count(!!sym(group_var), Life_stage_exposed, name = "n") %>%
    group_by(!!sym(group_var)) %>%
    mutate(proportion = n / sum(n)) %>%
    ungroup() %>% 
    rename(`Life stage exposed` = Life_stage_exposed)
}

Journals

# Life stage exposed by Journal
life_stage_by_journal_exp <- split_and_summarise(data, "Journal")

flextable(life_stage_by_journal_exp) %>%
  autofit() %>%
  set_caption("Life stages exposed across journals") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages exposed across journals

Journal

Life stage exposed

n

proportion

Conservation Physiology

Unclear

20

0.10050251

Conservation Physiology

Mix (strictly after hatching)

6

0.03015075

Conservation Physiology

Mix (before and after hatching)

2

0.01005025

Conservation Physiology

Embryos

24

0.12060302

Conservation Physiology

Larvae or juveniles

82

0.41206030

Conservation Physiology

Adults

65

0.32663317

Journal of Experimental Biology

Unclear

26

0.04384486

Journal of Experimental Biology

Mix (strictly after hatching)

17

0.02866779

Journal of Experimental Biology

Mix (before and after hatching)

29

0.04890388

Journal of Experimental Biology

Embryos

49

0.08263069

Journal of Experimental Biology

Larvae or juveniles

115

0.19392917

Journal of Experimental Biology

Adults

357

0.60202361

Journal of Thermal Biology

Unclear

36

0.05970149

Journal of Thermal Biology

Mix (strictly after hatching)

8

0.01326700

Journal of Thermal Biology

Mix (before and after hatching)

28

0.04643449

Journal of Thermal Biology

Embryos

58

0.09618574

Journal of Thermal Biology

Larvae or juveniles

205

0.33996683

Journal of Thermal Biology

Adults

268

0.44444444

Trait categories

# Life stage exposed by Trait category
life_stage_by_trait_exp <- split_and_summarise(data, "Trait_category")

flextable(life_stage_by_trait_exp) %>%
  autofit() %>%
  set_caption("Life stages exposed across trait categories") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages exposed across trait categories

Trait_category

Life stage exposed

n

proportion

Cardiovascular physiology

Unclear

11

0.088709677

Cardiovascular physiology

Mix (strictly after hatching)

1

0.008064516

Cardiovascular physiology

Mix (before and after hatching)

4

0.032258065

Cardiovascular physiology

Embryos

9

0.072580645

Cardiovascular physiology

Larvae or juveniles

22

0.177419355

Cardiovascular physiology

Adults

77

0.620967742

Development

Unclear

12

0.027906977

Development

Mix (strictly after hatching)

8

0.018604651

Development

Mix (before and after hatching)

32

0.074418605

Development

Embryos

85

0.197674419

Development

Larvae or juveniles

185

0.430232558

Development

Adults

108

0.251162791

Energetics and metabolism

Unclear

32

0.052892562

Energetics and metabolism

Mix (strictly after hatching)

13

0.021487603

Energetics and metabolism

Mix (before and after hatching)

12

0.019834711

Energetics and metabolism

Embryos

41

0.067768595

Energetics and metabolism

Larvae or juveniles

180

0.297520661

Energetics and metabolism

Adults

327

0.540495868

Environmental tolerance and preference

Unclear

57

0.071608040

Environmental tolerance and preference

Mix (strictly after hatching)

18

0.022613065

Environmental tolerance and preference

Mix (before and after hatching)

36

0.045226131

Environmental tolerance and preference

Embryos

69

0.086683417

Environmental tolerance and preference

Larvae or juveniles

231

0.290201005

Environmental tolerance and preference

Adults

385

0.483668342

Immune function and stress physiology

Unclear

16

0.061776062

Immune function and stress physiology

Mix (strictly after hatching)

3

0.011583012

Immune function and stress physiology

Mix (before and after hatching)

3

0.011583012

Immune function and stress physiology

Embryos

16

0.061776062

Immune function and stress physiology

Larvae or juveniles

85

0.328185328

Immune function and stress physiology

Adults

136

0.525096525

Osmoregulation

Unclear

20

0.114285714

Osmoregulation

Mix (strictly after hatching)

9

0.051428571

Osmoregulation

Mix (before and after hatching)

3

0.017142857

Osmoregulation

Embryos

9

0.051428571

Osmoregulation

Larvae or juveniles

34

0.194285714

Osmoregulation

Adults

100

0.571428571

Other

Unclear

1

0.111111111

Other

Embryos

2

0.222222222

Other

Larvae or juveniles

4

0.444444444

Other

Adults

2

0.222222222

Reproduction

Unclear

2

0.011976048

Reproduction

Mix (strictly after hatching)

7

0.041916168

Reproduction

Mix (before and after hatching)

16

0.095808383

Reproduction

Embryos

21

0.125748503

Reproduction

Larvae or juveniles

33

0.197604790

Reproduction

Adults

88

0.526946108

Taxonomic groups

# Life stage exposed by Taxonomic_group
life_stage_by_taxa_exp <- split_and_summarise(data, "Taxonomic_group")

flextable(life_stage_by_taxa_exp) %>%
  autofit() %>%
  set_caption("Life stages exposed across taxonomic groups") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages exposed across taxonomic groups

Taxonomic_group

Life stage exposed

n

proportion

Amphibian

Unclear

4

0.050000000

Amphibian

Mix (strictly after hatching)

1

0.012500000

Amphibian

Mix (before and after hatching)

4

0.050000000

Amphibian

Embryos

8

0.100000000

Amphibian

Larvae or juveniles

33

0.412500000

Amphibian

Adults

30

0.375000000

Bird

Unclear

7

0.060869565

Bird

Mix (strictly after hatching)

1

0.008695652

Bird

Embryos

21

0.182608696

Bird

Larvae or juveniles

26

0.226086957

Bird

Adults

60

0.521739130

Fish

Unclear

36

0.085918854

Fish

Mix (strictly after hatching)

9

0.021479714

Fish

Mix (before and after hatching)

9

0.021479714

Fish

Embryos

37

0.088305489

Fish

Larvae or juveniles

166

0.396181384

Fish

Adults

162

0.386634845

Insect

Unclear

3

0.010238908

Insect

Mix (strictly after hatching)

6

0.020477816

Insect

Mix (before and after hatching)

26

0.088737201

Insect

Embryos

24

0.081911263

Insect

Larvae or juveniles

96

0.327645051

Insect

Adults

138

0.470989761

Mammal

Unclear

9

0.064285714

Mammal

Mix (before and after hatching)

2

0.014285714

Mammal

Embryos

2

0.014285714

Mammal

Larvae or juveniles

17

0.121428571

Mammal

Adults

110

0.785714286

Other invertebrate

Unclear

16

0.064777328

Other invertebrate

Mix (strictly after hatching)

12

0.048582996

Other invertebrate

Mix (before and after hatching)

17

0.068825911

Other invertebrate

Embryos

19

0.076923077

Other invertebrate

Larvae or juveniles

50

0.202429150

Other invertebrate

Adults

133

0.538461538

Reptile

Unclear

9

0.084112150

Reptile

Mix (strictly after hatching)

2

0.018691589

Reptile

Mix (before and after hatching)

1

0.009345794

Reptile

Embryos

22

0.205607477

Reptile

Larvae or juveniles

15

0.140186916

Reptile

Adults

58

0.542056075

Climate change stressors

# Life stage exposed by Climate_change_stressor
life_stage_by_stressor_exp <- split_and_summarise(data, "Climate_change_stressor")

flextable(life_stage_by_stressor_exp) %>%
  autofit() %>%
  set_caption("Life stages exposed across climate change stressors") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages exposed across climate change stressors

Climate_change_stressor

Life stage exposed

n

proportion

Humidity/Water availability

Unclear

4

0.064516129

Humidity/Water availability

Mix (strictly after hatching)

2

0.032258065

Humidity/Water availability

Mix (before and after hatching)

1

0.016129032

Humidity/Water availability

Embryos

2

0.032258065

Humidity/Water availability

Larvae or juveniles

6

0.096774194

Humidity/Water availability

Adults

47

0.758064516

Interaction with non-climatic stressor

Unclear

7

0.048611111

Interaction with non-climatic stressor

Mix (strictly after hatching)

2

0.013888889

Interaction with non-climatic stressor

Mix (before and after hatching)

4

0.027777778

Interaction with non-climatic stressor

Embryos

7

0.048611111

Interaction with non-climatic stressor

Larvae or juveniles

58

0.402777778

Interaction with non-climatic stressor

Adults

66

0.458333333

Other

Embryos

1

0.058823529

Other

Larvae or juveniles

8

0.470588235

Other

Adults

8

0.470588235

Oâ‚‚/COâ‚‚

Unclear

11

0.053921569

Oâ‚‚/COâ‚‚

Mix (strictly after hatching)

4

0.019607843

Oâ‚‚/COâ‚‚

Mix (before and after hatching)

2

0.009803922

Oâ‚‚/COâ‚‚

Embryos

24

0.117647059

Oâ‚‚/COâ‚‚

Larvae or juveniles

54

0.264705882

Oâ‚‚/COâ‚‚

Adults

109

0.534313725

Salinity

Unclear

11

0.150684932

Salinity

Mix (strictly after hatching)

5

0.068493151

Salinity

Mix (before and after hatching)

2

0.027397260

Salinity

Embryos

5

0.068493151

Salinity

Larvae or juveniles

23

0.315068493

Salinity

Adults

27

0.369863014

Temperature

Unclear

62

0.054243220

Temperature

Mix (strictly after hatching)

24

0.020997375

Temperature

Mix (before and after hatching)

51

0.044619423

Temperature

Embryos

107

0.093613298

Temperature

Larvae or juveniles

340

0.297462817

Temperature

Adults

559

0.489063867

pH

Unclear

8

0.086021505

pH

Mix (strictly after hatching)

3

0.032258065

pH

Mix (before and after hatching)

7

0.075268817

pH

Embryos

7

0.075268817

pH

Larvae or juveniles

31

0.333333333

pH

Adults

37

0.397849462

Data summary by life stage (assessed for physiological traits)

Here, data summaries are generated separately for each life stage. In this study, we differentiated the life stages exposed to climatic stressors (presented above), to those assessed for physiological stressors (presented here), as these sometimes differ, especially in the context of longitudinal studies.

Helper function

# Helper function for splitting + unnesting the different life stages
split_and_summarise2 <- function(data, group_var) {
  life_stage_order <- c("Unclear", "Embryos", "Larvae or juveniles", "Adults")
  data %>%
    mutate(across(all_of(c("Life_stage_tested", group_var)), ~ strsplit(as.character(.), ", "))) %>%
    unnest(Life_stage_tested) %>%
    unnest(all_of(group_var)) %>%
    mutate(Life_stage_tested = factor(Life_stage_tested, levels = life_stage_order)) %>%
    count(!!sym(group_var), Life_stage_tested, name = "n") %>%
    group_by(!!sym(group_var)) %>%
    mutate(proportion = n / sum(n)) %>%
    ungroup() %>% 
    rename(`Life stage tested` = Life_stage_tested)
}

Journals

# Life_stage_tested by Journal
life_stage_by_journal <- split_and_summarise2(data, "Journal")

flextable(life_stage_by_journal) %>%
  autofit() %>%
  set_caption("Life stages tested across journals") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages tested across journals

Journal

Life stage tested

n

proportion

Conservation Physiology

Unclear

20

0.09433962

Conservation Physiology

Embryos

19

0.08962264

Conservation Physiology

Larvae or juveniles

98

0.46226415

Conservation Physiology

Adults

75

0.35377358

Journal of Experimental Biology

Unclear

28

0.04341085

Journal of Experimental Biology

Embryos

45

0.06976744

Journal of Experimental Biology

Larvae or juveniles

172

0.26666667

Journal of Experimental Biology

Adults

400

0.62015504

Journal of Thermal Biology

Unclear

35

0.05409583

Journal of Thermal Biology

Embryos

56

0.08655332

Journal of Thermal Biology

Larvae or juveniles

243

0.37557960

Journal of Thermal Biology

Adults

313

0.48377125

Trait categories

# Life_stage_tested by Trait category
life_stage_by_trait <- split_and_summarise2(data, "Trait_category")

flextable(life_stage_by_trait) %>%
  autofit() %>%
  set_caption("Life stages tested across trait categories") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages tested across trait categories

Trait_category

Life stage tested

n

proportion

Cardiovascular physiology

Unclear

11

0.08333333

Cardiovascular physiology

Embryos

8

0.06060606

Cardiovascular physiology

Larvae or juveniles

32

0.24242424

Cardiovascular physiology

Adults

81

0.61363636

Development

Unclear

10

0.01984127

Development

Embryos

77

0.15277778

Development

Larvae or juveniles

255

0.50595238

Development

Adults

162

0.32142857

Energetics and metabolism

Unclear

33

0.05238095

Energetics and metabolism

Embryos

32

0.05079365

Energetics and metabolism

Larvae or juveniles

212

0.33650794

Energetics and metabolism

Adults

353

0.56031746

Environmental tolerance and preference

Unclear

59

0.06876457

Environmental tolerance and preference

Embryos

70

0.08158508

Environmental tolerance and preference

Larvae or juveniles

294

0.34265734

Environmental tolerance and preference

Adults

435

0.50699301

Immune function and stress physiology

Unclear

16

0.05904059

Immune function and stress physiology

Embryos

12

0.04428044

Immune function and stress physiology

Larvae or juveniles

98

0.36162362

Immune function and stress physiology

Adults

145

0.53505535

Osmoregulation

Unclear

21

0.10937500

Osmoregulation

Embryos

9

0.04687500

Osmoregulation

Larvae or juveniles

51

0.26562500

Osmoregulation

Adults

111

0.57812500

Other

Unclear

1

0.12500000

Other

Larvae or juveniles

5

0.62500000

Other

Adults

2

0.25000000

Reproduction

Unclear

3

0.01442308

Reproduction

Embryos

29

0.13942308

Reproduction

Larvae or juveniles

57

0.27403846

Reproduction

Adults

119

0.57211538

Taxonomic groups

# Life_stage_tested by Taxonomic_group
life_stage_by_taxa <- split_and_summarise2(data, "Taxonomic_group")

flextable(life_stage_by_taxa) %>%
  autofit() %>%
  set_caption("Life stages tested across taxonomic groups") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages tested across taxonomic groups

Taxonomic_group

Life stage tested

n

proportion

Amphibian

Unclear

4

0.048780488

Amphibian

Embryos

5

0.060975610

Amphibian

Larvae or juveniles

39

0.475609756

Amphibian

Adults

34

0.414634146

Bird

Unclear

7

0.055118110

Bird

Embryos

15

0.118110236

Bird

Larvae or juveniles

43

0.338582677

Bird

Adults

62

0.488188976

Fish

Unclear

37

0.084090909

Fish

Embryos

33

0.075000000

Fish

Larvae or juveniles

192

0.436363636

Fish

Adults

178

0.404545455

Insect

Unclear

3

0.009345794

Insect

Embryos

25

0.077881620

Insect

Larvae or juveniles

101

0.314641745

Insect

Adults

192

0.598130841

Mammal

Unclear

8

0.054794521

Mammal

Embryos

1

0.006849315

Mammal

Larvae or juveniles

22

0.150684932

Mammal

Adults

115

0.787671233

Other invertebrate

Unclear

18

0.064981949

Other invertebrate

Embryos

25

0.090252708

Other invertebrate

Larvae or juveniles

83

0.299638989

Other invertebrate

Adults

151

0.545126354

Reptile

Unclear

8

0.068376068

Reptile

Embryos

16

0.136752137

Reptile

Larvae or juveniles

34

0.290598291

Reptile

Adults

59

0.504273504

Climate change stressors

# Life_stage_tested by Climate_change_stressor
life_stage_by_stressor <- split_and_summarise2(data, "Climate_change_stressor")

flextable(life_stage_by_stressor) %>%
  autofit() %>%
  set_caption("Life stages tested across climate change stressors") %>%  
  bg(bg = "white", part = "all") %>%  
  color(color = "black", part = "all")
Life stages tested across climate change stressors

Climate_change_stressor

Life stage tested

n

proportion

Humidity/Water availability

Unclear

4

0.06250000

Humidity/Water availability

Embryos

2

0.03125000

Humidity/Water availability

Larvae or juveniles

8

0.12500000

Humidity/Water availability

Adults

50

0.78125000

Interaction with non-climatic stressor

Unclear

7

0.04545455

Interaction with non-climatic stressor

Embryos

7

0.04545455

Interaction with non-climatic stressor

Larvae or juveniles

64

0.41558442

Interaction with non-climatic stressor

Adults

76

0.49350649

Other

Embryos

1

0.05555556

Other

Larvae or juveniles

8

0.44444444

Other

Adults

9

0.50000000

Oâ‚‚/COâ‚‚

Unclear

12

0.05529954

Oâ‚‚/COâ‚‚

Embryos

18

0.08294931

Oâ‚‚/COâ‚‚

Larvae or juveniles

67

0.30875576

Oâ‚‚/COâ‚‚

Adults

120

0.55299539

Salinity

Unclear

12

0.15000000

Salinity

Embryos

5

0.06250000

Salinity

Larvae or juveniles

31

0.38750000

Salinity

Adults

32

0.40000000

Temperature

Unclear

62

0.05040650

Temperature

Embryos

97

0.07886179

Temperature

Larvae or juveniles

429

0.34878049

Temperature

Adults

642

0.52195122

pH

Unclear

8

0.07766990

pH

Embryos

11

0.10679612

pH

Larvae or juveniles

44

0.42718447

pH

Adults

40

0.38834951

Figures

Note that all figures were customised in Illustrator for cosmetic purposes.

Figure 1

Colour palettes and themes

# Creata colour palette
palette <- c(
  "Unclear" = "gray70",       
  "Embryos" = "#E6AB02",       
  "Larvae or juveniles" = "#7570B3",  
  "Adults" = "#1B9E77",
  "Mix (before and after hatching)" = "#7D9364",
  "Mix (strictly after hatching)" = "#AE8E5B")

# Create custom theme
custom_theme <- theme_minimal(base_size = 14) +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.line = element_line(color = "black", linewidth = 0.4),
    axis.ticks = element_line(color = "black"),
    axis.text.y = element_text(size = 16, hjust = 1, color = "black"),
    axis.text.x = element_text(size = 15),
    axis.title.x = element_text(size = 24),
    axis.title.y = element_blank(),
    legend.title = element_text(size = 16),
    legend.text = element_text(size = 14),
    legend.position = c(0.95, 0.05),
    legend.justification = c("right", "bottom"),
    legend.background = element_blank(),
    panel.border = element_rect(color = "black", fill = NA, size = 1.25))

Combine plots

figure_1 <- (stream_plot /  journal_plot) + 
  plot_annotation(tag_levels = "a", tag_suffix = ".") & theme(plot.tag = element_text(size = 35))

figure_1

ggsave(figure_1, file = "Fig/figure_1.svg", width=30, height = 20, dpi = 1200)

Figure 2

Combine plots

figure_2 <- (trait_plot /  taxa_plot / stressor_plot) + 
  plot_annotation(tag_levels = "a", tag_suffix = ".") & theme(plot.tag = element_text(size = 35))

figure_2

ggsave(figure_2, file = "Fig/figure_2.svg", width=40, height = 30, dpi = 1200, limitsize = FALSE)

Figure 3

Cord diagram to visualise studies with single vs multiple life stages

categories <- c("Adults", "Larvae or juveniles", "Embryos")

# Parse life stages
data <- data %>% 
  mutate(lifestages = strsplit(Life_stage_tested, ",\\s*") %>% map(trimws))

# Dummy list to store matrix
dummy_list <- data %>% 
  mutate(dummy = map(lifestages, ~ as.integer(categories %in% .x))) %>% 
  pull(dummy) %>% 
  map(~ setNames(.x, categories))

# Add names to each dummy vector
dummy_list <- map(dummy_list, ~ setNames(.x, categories))

# Sum the outer products of the dummy vectors to form a co-occurrence matrix.
# Each record contributes an outer product: if a record has both "Adults" and "Embryos", 
# then outer(vec, vec) returns a matrix with a 1 in that cell.
NetMatrix_lifestage <- Reduce("+", lapply(dummy_list, function(vec) outer(vec, vec)))

# Separate cases where there is a single vs. multiple life stages
exclusive_counts <- sapply(categories, function(cat) {
  sum(lengths(data$lifestages) == 1 & vapply(data$lifestages, function(x) x[1] == cat, logical(1)))
})

diag(NetMatrix_lifestage) <- exclusive_counts   # replace diagonal
NetMatrix_lifestage[lower.tri(NetMatrix_lifestage)] <- 0  # Remove duplicated information

# Check the matrix
print(NetMatrix_lifestage)
##                     Adults Larvae or juveniles Embryos
## Adults                 635                 142      36
## Larvae or juveniles      0                 321      75
## Embryos                  0                   0      34
# Create the chord diagram
#pdf(file ="Fig/figure_3.pdf", width = 8, height = 8, pointsize = 10)
png(file ="Fig/figure_3.png", pointsize = 4.5, res = 1000, width = 10, height = 10, unit = "cm",)

circos.par(gap.after = c(2,2,2)) # Adjust space between categories
figure_3 <- chordDiagram(NetMatrix_lifestage, 
                      annotationTrack = "grid", 
                      preAllocateTracks = 1, 
                      grid.col = palette,
                      self.link = 1) # Don't duplicate data

# Remove the sector names (labels) and just display the axis (numbers/ticks)
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim <- get.cell.meta.data("xlim")
  ylim <- get.cell.meta.data("ylim")
  sector.name <- get.cell.meta.data("sector.index")
  circos.axis(h = "top", labels.cex = 0.75, major.tick.length = 0.2, 
              sector.index = sector.name, track.index = 2)
}, bg.border = NA)

figure_3
##                    rn                  cn value1 value2 o1 o2  x1  x2       col
## 1              Adults              Adults    635    635  3  0 813 813 #1B9E777F
## 2 Larvae or juveniles              Adults      0      0  1  5   0 813 #7570B37F
## 3             Embryos              Adults      0      0  2  4   0 813 #E6AB027F
## 4              Adults Larvae or juveniles    142    142  2  4 178 538 #1B9E777F
## 5 Larvae or juveniles Larvae or juveniles    321    321  3  0 396 396 #7570B37F
## 6             Embryos Larvae or juveniles      0      0  1  5   0 538 #E6AB027F
## 7              Adults             Embryos     36     36  1  5  36 145 #1B9E777F
## 8 Larvae or juveniles             Embryos     75     75  2  4  75 109 #7570B37F
## 9             Embryos             Embryos     34     34  3  0  34  34 #E6AB027F
dev.off()
## png 
##   2

Supplementary figures

Figure S1

This figure was generated in powerpoint.

Figure S2

This figure reproduces the patterns in figure 1, but only keeping studies measuring responses to temperature (i.e., the most common climatic stressor)

Combine plots

figure_S2 <- (stream_plot_temp /  journal_plot_temp) + 
  plot_annotation(tag_levels = "a", tag_suffix = ".") & theme(plot.tag = element_text(size = 35))

figure_S2

ggsave(figure_S2, file = "Fig/figure_S2.svg", width=20, height = 15, dpi = 1200)

Figure S3

This figure reproduces the patterns in figure 2, but only keeping studies measuring responses to temperature (i.e., the most common climatic stressor).

Combine plots

figure_S3 <- (trait_plot_temp /  taxa_plot_temp) + 
  plot_annotation(tag_levels = "a", tag_suffix = ".") & theme(plot.tag = element_text(size = 35))

figure_S3

ggsave(figure_S3, file = "Fig/figure_S3.svg", width=35, height = 20, dpi = 1200, limitsize = FALSE)

Figure S4

This figure reproduces the patterns in figure 3, but only keeping studies measuring responses to temperature (i.e., the most common climatic stressor).

categories <- c("Adults", "Larvae or juveniles", "Embryos")

# Parse life stages
data_temp <- data_temp %>% 
  mutate(lifestages = strsplit(Life_stage_tested, ",\\s*") %>% map(trimws))

# Dummy list to store matrix
dummy_list_temp <- data_temp %>% 
  mutate(dummy = map(lifestages, ~ as.integer(categories %in% .x))) %>% 
  pull(dummy) %>% 
  map(~ setNames(.x, categories))

# Add names to each dummy vector
dummy_list_temp <- map(dummy_list_temp, ~ setNames(.x, categories))

# Sum the outer products of the dummy vectors to form a co-occurrence matrix.
# Each record contributes an outer product: if a record has both "Adults" and "Embryos", 
# then outer(vec, vec) returns a matrix with a 1 in that cell.
NetMatrix_lifestage_temp <- Reduce("+", lapply(dummy_list_temp, function(vec) outer(vec, vec)))

# Separate cases where there is a single vs. multiple life stages
exclusive_counts_temp <- sapply(categories, function(cat) {
  sum(lengths(data_temp$lifestages) == 1 & vapply(data_temp$lifestages, function(x) x[1] == cat, logical(1)))
})

diag(NetMatrix_lifestage_temp) <- exclusive_counts_temp   # replace diagonal
NetMatrix_lifestage_temp[lower.tri(NetMatrix_lifestage_temp)] <- 0  # Remove duplicated information

# Check the matrix
print(NetMatrix_lifestage_temp)
##                     Adults Larvae or juveniles Embryos
## Adults                 387                  96      28
## Larvae or juveniles      0                 180      52
## Embryos                  0                   0      19
# Create the chord diagram
png(file ="Fig/figure_S4.png", pointsize = 4.5, res = 1000, width = 10, height = 10, unit = "cm",)

circos.par(gap.after = c(2,2,2)) # Adjust space between categories
figure_S4 <- chordDiagram(NetMatrix_lifestage_temp, 
                      annotationTrack = "grid", 
                      preAllocateTracks = 1, 
                      grid.col = palette,
                      self.link = 1) # Don't duplicate data

# Remove the sector names (labels) and just display the axis (numbers/ticks)
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim <- get.cell.meta.data("xlim")
  ylim <- get.cell.meta.data("ylim")
  sector.name <- get.cell.meta.data("sector.index")
  circos.axis(h = "top", labels.cex = 0.75, major.tick.length = 0.2, 
              sector.index = sector.name, track.index = 2)
}, bg.border = NA)

figure_S4
##                    rn                  cn value1 value2 o1 o2  x1  x2       col
## 1              Adults              Adults    387    387  3  0 511 511 #1B9E777F
## 2 Larvae or juveniles              Adults      0      0  1  5   0 511 #7570B37F
## 3             Embryos              Adults      0      0  2  4   0 511 #E6AB027F
## 4              Adults Larvae or juveniles     96     96  2  4 124 328 #1B9E777F
## 5 Larvae or juveniles Larvae or juveniles    180    180  3  0 232 232 #7570B37F
## 6             Embryos Larvae or juveniles      0      0  1  5   0 328 #E6AB027F
## 7              Adults             Embryos     28     28  1  5  28  99 #1B9E777F
## 8 Larvae or juveniles             Embryos     52     52  2  4  52  71 #7570B37F
## 9             Embryos             Embryos     19     19  3  0  19  19 #E6AB027F
dev.off()
## png 
##   2

Package versions

sessionInfo()
## R version 4.4.2 (2024-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26100)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=English_Australia.utf8  LC_CTYPE=English_Australia.utf8   
## [3] LC_MONETARY=English_Australia.utf8 LC_NUMERIC=C                      
## [5] LC_TIME=English_Australia.utf8    
## 
## time zone: Europe/Berlin
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] patchwork_1.3.0    circlize_0.4.16    bib2df_1.1.2.0     bibliometrix_4.3.4
##  [5] flextable_0.9.7    ggstream_0.1.0     lubridate_1.9.4    forcats_1.0.0     
##  [9] stringr_1.5.1      dplyr_1.1.4        purrr_1.0.2        readr_2.1.5       
## [13] tidyr_1.3.1        tibble_3.2.1       ggplot2_3.5.1      tidyverse_2.0.0   
## 
## loaded via a namespace (and not attached):
##   [1] readxl_1.4.3            rlang_1.1.4             magrittr_2.0.3         
##   [4] tidytext_0.4.2          compiler_4.4.2          openalexR_1.4.0        
##   [7] systemfonts_1.2.2       vctrs_0.6.5             crayon_1.5.3           
##  [10] pkgconfig_2.0.3         shape_1.4.6.1           fastmap_1.2.0          
##  [13] labeling_0.4.3          rmdformats_1.0.4        ca_0.71.1              
##  [16] promises_1.3.2          rmarkdown_2.29          tzdb_0.4.0             
##  [19] ragg_1.3.3              bit_4.6.0               xfun_0.52              
##  [22] cachem_1.1.0            jsonlite_1.8.9          SnowballC_0.7.1        
##  [25] later_1.4.1             uuid_1.2-1              parallel_4.4.2         
##  [28] R6_2.6.1                bslib_0.9.0             stringi_1.8.4          
##  [31] jquerylib_0.1.4         cellranger_1.1.0        Rcpp_1.0.14            
##  [34] bookdown_0.42           knitr_1.50              httpuv_1.6.15          
##  [37] rentrez_1.2.3           Matrix_1.7-1            igraph_2.1.4           
##  [40] timechange_0.3.0        tidyselect_1.2.1        rstudioapi_0.17.1      
##  [43] stringdist_0.9.15       pubmedR_0.0.3           yaml_2.3.10            
##  [46] codetools_0.2-20        humaniformat_0.6.0      lattice_0.22-6         
##  [49] plyr_1.8.9              shiny_1.10.0            withr_3.0.2            
##  [52] askpass_1.2.1           evaluate_1.0.3          zip_2.3.2              
##  [55] xml2_1.3.8              pillar_1.10.2           janeaustenr_1.0.0      
##  [58] DT_0.33                 plotly_4.10.4           generics_0.1.3         
##  [61] vroom_1.6.5             hms_1.1.3               munsell_0.5.1          
##  [64] scales_1.3.0            xtable_1.8-4            glue_1.8.0             
##  [67] gdtools_0.4.1           lazyeval_0.2.2          tools_4.4.2            
##  [70] data.table_1.17.0       tokenizers_0.3.0        openxlsx_4.2.8         
##  [73] visNetwork_2.1.2        XML_3.99-0.18           grid_4.4.2             
##  [76] rscopus_0.6.6           colorspace_2.1-1        dimensionsR_0.0.3      
##  [79] bibliometrixData_0.3.0  cli_3.6.3               textshaping_1.0.0      
##  [82] officer_0.6.8           fontBitstreamVera_0.1.1 viridisLite_0.4.2      
##  [85] svglite_2.1.3           gtable_0.3.6            sass_0.4.9             
##  [88] digest_0.6.37           fontquiver_0.2.1        ggrepel_0.9.6          
##  [91] htmlwidgets_1.6.4       farver_2.1.2            htmltools_0.5.8.1      
##  [94] lifecycle_1.0.4         httr_1.4.7              GlobalOptions_0.1.2    
##  [97] mime_0.13               bit64_4.6.0-1           fontLiberation_0.1.0   
## [100] openssl_2.3.2
LS0tDQp0aXRsZTogIioqRW1icnlvcyBhcmUgbGFyZ2VseSB1bmRlcnN0dWRpZWQgaW4gY29uc2VydmF0aW9uIHBoeXNpb2xvZ3kqKiINCmF1dGhvcjogUGF0cmljZSBQb3R0aWVyDQpkYXRlOiAibGF0ZXN0IHVwZGF0ZTogYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCINCm91dHB1dDogDQogIHJtZGZvcm1hdHM6OmRvd25jdXRlOg0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2NfZGVwdGg6IDYNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICB0aHVtYm5haWxzOiBmYWxzZQ0KICAgIGRvd25jdXRlX3RoZW1lOiAiY2hhb3MiDQogICAgY29kZV9vdmVyZmxvdzogd3JhcA0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCg0KPHN0eWxlPg0KI3RvYyB1bC5uYXYgbGkgdWwgbGkgew0KICAgIGRpc3BsYXk6IG5vbmU7DQogICAgbWF4LWhlaWdodDogbm9uZTsNCn0NCg0KI3RvYyB1bC5uYXYgbGkuYWN0aXZlIHVsIGxpICB7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgbWF4LWhlaWdodDogbm9uZTsNCn0NCg0KI3RvYyB1bC5uYXYgbGkgdWwgbGkgdWwgbGkgew0KICAgIG1heC1oZWlnaHQ6IG5vbmU7DQogICAgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50Ow0KfQ0KDQojdG9jIHVsLm5hdiBsaSB1bCBsaS5hY3RpdmUgdWwgbGkgew0KICAgIG1heC1oZWlnaHQ6IG5vbmU7DQogICAgZGlzcGxheTogYmxvY2sgIWltcG9ydGFudDsNCiAgICANCn0NCg0KaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7DQogICAgY29sb3I6IGRhcmt0dXJxdW9pc2UgIWltcG9ydGFudDsNCg0KPC9zdHlsZT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KIyBrbml0ciBzZXR0aW5nDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLCANCiAgdGlkeSA9IFRSVUUsDQogIGNhY2hlID0gVFJVRSwNCiAgZWNobz1UUlVFDQopDQpgYGANCg0KDQojICoqTG9hZCByZWxldmFudCBwYWNrYWdlcyoqIA0KYGBge3J9DQpwYWNtYW46OnBfbG9hZCh0aWR5dmVyc2UsDQogICAgICAgICAgICAgICBnZ3N0cmVhbSwNCiAgICAgICAgICAgICAgIGZsZXh0YWJsZSwNCiAgICAgICAgICAgICAgIGJpYmxpb21ldHJpeCwNCiAgICAgICAgICAgICAgIGJpYjJkZiwNCiAgICAgICAgICAgICAgIGNpcmNsaXplLA0KICAgICAgICAgICAgICAgcGF0Y2h3b3JrKSAjIHBfbG9hZCgpIHdpbGwgaW5zdGFsbCBwYWNrYWdlcyBpZiB0aGV5IGFyZSBub3QgaW5zdGFsbGVkIGFscmVhZHkNCnNldC5zZWVkKDEyMykNCmBgYA0KDQojICoqSW1wb3J0IGRhdGEqKg0KYGBge3J9DQojIEltcG9ydCBzdXJ2ZXkgZGF0YQ0KcmF3X2RhdGEgPC0gcmVhZF9jc3YoIkRhdGEvZXh0cmFjdGVkX2RhdGFfY29uc19waHlzX2xpZmVfc3RhZ2VzLmNzdiIpDQoNCiMgUmVtb3ZlIHNwYWNlcyBpbiBjb2x1bW4gbmFtZXMNCmNvbG5hbWVzKHJhd19kYXRhKSA8LSBnc3ViKCIgIiwgIl8iLCBjb2xuYW1lcyhyYXdfZGF0YSkpDQpgYGANCg0KIyAqKkRhdGEgY2xlYW5pbmcqKg0KDQpgYGB7cn0NCiMgRml4IHNvbWUgdHlwb3MsIHRpdGxlcyBzd2FwcGVkIHdpdGggdGhlIHJlZmVyZW5jZSBpbmZvcm1hdGlvbiwgb3IgbWlzc2luZyBwdWJsaWNhdGlvbiB5ZWFycw0KZGF0YSA8LSByYXdfZGF0YQ0KZGF0YSRTaG9ydF9yZWZlcmVuY2VbZGF0YSRTaG9ydF9yZWZlcmVuY2UgPT0gIklsbGluZ19ldF9hbF8yMDI5Il0gPC0gIklsbGluZ19ldF9hbF8yMDIwIg0KZGF0YSRTaG9ydF9yZWZlcmVuY2VbZGF0YSRTaG9ydF9yZWZlcmVuY2UgPT0gIlNoYXJ0YXVfZXRfYWxfMjAwMiJdIDwtICJTaGFydGF1X2V0X2FsXzIwMTYiDQpkYXRhJFNob3J0X3JlZmVyZW5jZVtkYXRhJFNob3J0X3JlZmVyZW5jZSA9PSAiQWJkZWxxYWRlcl9hbmRfQWwtRmF0YWZ0YWgiXSA8LSAiQWJkZWxxYWRlcl9hbmRfQWwtRmF0YWZ0YWhfMjAxNCINCmRhdGEkU2hvcnRfcmVmZXJlbmNlW2RhdGEkU2hvcnRfcmVmZXJlbmNlID09ICJXaWVkZW5vdmFfZXRfYWxfIl0gPC0gIldpZWRlbm92YV9ldF9hbF8yMDE4Ig0KZGF0YSRTaG9ydF9yZWZlcmVuY2VbZGF0YSRTaG9ydF9yZWZlcmVuY2UgPT0gIlJhZHVnaW5hX2FuZF9Hcmlnb3J5YW4iXSA8LSAiUmFkdWdpbmFfYW5kX0dyaWdvcnlhbl8yMDE4Ig0KDQpkYXRhJFNob3J0X3JlZmVyZW5jZVtkYXRhJFNob3J0X3JlZmVyZW5jZSA9PSAiQWN1dGUgdGhlcm1hbCBzdHJlc3MgYW5kIGVuZG90b3hpbiBleHBvc3VyZSBtb2R1bGF0ZSBtZXRhYm9saXNtIGFuZCBpbW11bml0eSBpbiBtYXJpbmUgbXVzc2VscyAoUGVybmEgY2FuYWxpY3VsdXMpIl0gPC0gIk11em5lYmluX2V0X2FsXzIwMjIiDQpkYXRhJFRpdGxlW2RhdGEkU2hvcnRfcmVmZXJlbmNlID09ICJNdXpuZWJpbl9ldF9hbF8yMDIyIl0gPC0gIkFjdXRlIHRoZXJtYWwgc3RyZXNzIGFuZCBlbmRvdG94aW4gZXhwb3N1cmUgbW9kdWxhdGUgbWV0YWJvbGlzbSBhbmQgaW1tdW5pdHkgaW4gbWFyaW5lIG11c3NlbHMgKFBlcm5hIGNhbmFsaWN1bHVzKSINCmRhdGEkU2hvcnRfcmVmZXJlbmNlW2RhdGEkU2hvcnRfcmVmZXJlbmNlID09ICJIZWF0IHN0cmVzcyBpcyBhc3NvY2lhdGVkIHdpdGggZGlzcnVwdGlvbiBvZiBpb24gYmFsYW5jZSBpbiB0aGUgbWlncmF0b3J5IGxvY3VzdCwgTG9jdXN0YSBtaWdyYXRvcmlhIl0gPC0gIk8nU3VsbGl2YW5fZXRfYWxfMjAxNyINCmRhdGEkVGl0bGVbZGF0YSRTaG9ydF9yZWZlcmVuY2UgPT0gIk8nU3VsbGl2YW5fZXRfYWxfMjAxNyJdIDwtICJIZWF0IHN0cmVzcyBpcyBhc3NvY2lhdGVkIHdpdGggZGlzcnVwdGlvbiBvZiBpb24gYmFsYW5jZSBpbiB0aGUgbWlncmF0b3J5IGxvY3VzdCwgTG9jdXN0YSBtaWdyYXRvcmlhIg0KDQpkYXRhIDwtIGRhdGEgJT4lIGZpbHRlcihUaXRsZSAhPSAiUGh5c2lvbG9naWNhbCBjb3JyZWxhdGVzIG9mIHN5bWJpb250IG1pZ3JhdGlvbiBkdXJpbmcgYmxlYWNoaW5nIG9mIHR3byBvY3RvY29yYWwgc3BlY2llcyIpDQpkYXRhJFRpdGxlW2RhdGEkVGl0bGUgPT0gIlBoeXNpb2xvZ2ljYWwgY29ycmVsYXRlcyBvZiBzeW1iaW9udCBtaWdyYXRpb24gZHVyaW5nIGJsZWFjaGluZyBvZiB0d28gb2N0b2NvcmFsIHNwZWNpZXMgIEthdGhhcmluYSJdIDwtICJQaHlzaW9sb2dpY2FsIGNvcnJlbGF0ZXMgb2Ygc3ltYmlvbnQgbWlncmF0aW9uIGR1cmluZyBibGVhY2hpbmcgb2YgdHdvIG9jdG9jb3JhbCBzcGVjaWVzIg0KICANCiMgUmVtb3ZlIGR1cGxpY2F0ZXMgDQpkYXRhICU+JSBncm91cF9ieShUaXRsZSkgJT4lIHN1bW1hcmlzZShuPW4oKSkgJT4lIGZpbHRlcihuPjEpICMgQ2hlY2sgaWYgYW55IHRpdGxlIGlzIGR1cGxpY2F0ZWQNCmRhdGEgPC0gZGF0YSAlPiUgZGlzdGluY3QoVGl0bGUsIC5rZWVwX2FsbCA9IFRSVUUpICMgUmVtb3ZlIGR1cGxpY2F0ZQ0KDQojIENyZWF0ZSBhIGNvbHVtbiBmb3IgcHVibGljYXRpb24geWVhcg0KZGF0YSA8LSBkYXRhICU+JQ0KICBtdXRhdGUoUHVibGljYXRpb25feWVhciA9IGFzLmludGVnZXIoc3RyX2V4dHJhY3QoU2hvcnRfcmVmZXJlbmNlLCAiXFxkezR9IikpKQ0KDQojIFJlbmFtZSBjb2x1bW5zDQpkYXRhIDwtIHJlbmFtZShkYXRhLCANCiAgICAgICAgICAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9IExpZmVfc3RhZ2VfZXhwb3NlZF90b190aGVfc3RyZXNzb3IsDQogICAgICAgICAgICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9IExpZmVfc3RhZ2Vfb2ZfdGhlX2FuaW1hbHNfd2hlbl90cmFpdHNfd2VyZV9tZWFzdXJlZCkNCg0KIyBWaWV3IFRyYWl0IGNhdGVnb3JpZXMNCiNWaWV3KGRhdGEuZnJhbWUodGFibGUocmF3X2RhdGEkVHJhaXRfY2F0ZWdvcnkpKSkNCg0KIyBEZWxldGUgYW5kIHJlbmFtZSBzb21lIG9ic2VydmF0aW9ucyBmb3IgdHJhaXQgY2F0ZWdvcmllcw0KZGF0YSA8LSBkYXRhICU+JSANCiAgZmlsdGVyKFRyYWl0X2NhdGVnb3J5ICE9ICJCaW9tZWNoYW5pY3MiLA0KICAgICAgICAgVHJhaXRfY2F0ZWdvcnkgIT0gIm1pY3JvIFJOQSBleHByZXNzaW9uIikgJT4lIA0KICBtdXRhdGUoVHJhaXRfY2F0ZWdvcnkgPSBjYXNlX3doZW4oDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiUmVzdGluZyBtZW1icmFuZSBwb3RlbnRpYWwiIH4gIkVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20iLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkROQSBkYW1hZ2UiIH4gIkltbXVuZSBmdW5jdGlvbiBhbmQgc3RyZXNzIHBoeXNpb2xvZ3kiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20sIEhhZW1hdG9sb2d5IiB+ICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBDYXJkaW92YXNjdWxhciBwaHlzaW9sb2d5IiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBPc21vcmVndWxhdGlvbiwgRkxJR0hUIEFDVElWSVRZLCBBTExPTUVUUklDIE1FQVNVUkVTLCBDdXRpY3VsYXIgaHlkcm9jYXJib25zLEFLSC1yZWxhdGVkIGdlbmUgZXhwcmVzc2lvbiB2YXJpYXRpb25zIiB+ICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBPc21vcmVndWxhdGlvbiIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIENhcmRpb3Zhc2N1bGFyIHBoeXNpb2xvZ3ksIFJlc3BpcmF0b3J5IHBoeXNpb2xvZ3kiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBDYXJkaW92YXNjdWxhciBwaHlzaW9sb2d5LCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgQ2xlYXJhbmNlIChmZWVkaW5nKSByYXRlIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIERldmVsb3BtZW50LCBBY2NsaW1hdGlvbiIgfiAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIERldmVsb3BtZW50IiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRGV2ZWxvcG1lbnQsIEJlaGF2aW9yIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRGV2ZWxvcG1lbnQiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBEZXZlbG9wbWVudCwgRW1icnlvIHBoeXNpb2xvZ3kiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBEZXZlbG9wbWVudCIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIERldmVsb3BtZW50LCB0aHlyb2lkIGZ1bmN0aW9uIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRGV2ZWxvcG1lbnQsIE90aGVyIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgQmVoYXZpb3IiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgQmVoYXZpb3IgYW5kIHBoeXNpb2xvZ3kiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgY29uZGl0aW9uIGZhY3RvciwgcmVsYXRpdmUgaW50ZXN0aW5hbCBtYXNzLCBhbmQgaGVwYXRvc29tYXRpYyBpbmRleCIgfiAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIEVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20sIERldmVsb3BtZW50IiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSwgQmVoYXZpb3JhbCByZXNwb25zZXMiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5IiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSwgRGV2ZWxvcG1lbnQsIEJlaGF2aW9yIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSwgRGV2ZWxvcG1lbnQiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBNb3JwaG9sb2d5IGFuZCBCZWhhdmlvciIgfiAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIEVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20iLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBPc21vcmVndWxhdGlvbiwgQmVoYXZpb3IiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBPc21vcmVndWxhdGlvbiIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIEVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20sIFBlcmZvcm1hbmNlIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIGd1dCBtaWNyb2Jpb21lIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgT3RoZXIiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5LCB0aHlyb2lkIGhvcm1vbmVzIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSwgT3RoZXIiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBOZXVyb3BoeXNpb2xvZ3kiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBPdGhlciIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIFBlcmZvcm1hbmNlIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UsIHBob3RvY2hlbWljYWwgcGFyYW1ldGVycy9zeW1iaW9udCBkZW5zaXR5IiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgT3RoZXIiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBQaHlzaW9sb2d5IGFuZCBiZWhhdmlvciIgfiAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBSZXByb2R1Y3Rpb24sIGxpZmVzcGFuIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSwgUmVwcm9kdWN0aW9uLCBEZXZlbG9wbWVudCIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiZ2VuZSBleHByZXNzaW9uIG9mICdlbmVyZ3kgcmVndWxhdGlvbicgcGF0aHdheXMiIH4gIkVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20iLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkltbXVuZSBmdW5jdGlvbiBhbmQgc3RyZXNzIHBoeXNpb2xvZ3ksIERldmVsb3BtZW50LCBnZW5lIGV4cHJlc3Npb24iIH4gIkltbXVuZSBmdW5jdGlvbiBhbmQgc3RyZXNzIHBoeXNpb2xvZ3ksIERldmVsb3BtZW50IiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJtaXRvY2hvbmRyaWFsIG1lbWJyYW5lIHBvdGVudGlhbDsgcHJvdG9uIGxlYWs7IHJhdGlvIG9mIG1vbGVzIG9mIEFEUCBjb25zdW1lZCBwZXIgbW9sZSBvZiBveHlnZW4iIH4gIkVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20iLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIk9zbW9yZWd1bGF0aW9uLCBIeWRyb3JlZ3VsYXRpb24iIH4gIk9zbW9yZWd1bGF0aW9uIiwgICAgDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiT3Ntb3JlZ3VsYXRpb24sIEltbXVuZSBmdW5jdGlvbiBhbmQgc3RyZXNzIHBoeXNpb2xvZ3ksIGJlaGF2aW9yIiB+ICJPc21vcmVndWxhdGlvbiwgSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSIsICAgIA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIk9zbW9yZWd1bGF0aW9uLCBQZXJmb3JtYW5jZSIgfiAiT3Ntb3JlZ3VsYXRpb24iLCAgDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiT3Ntb3JlZ3VsYXRpb24sIFNlbnNvcnkgcGh5c2lvbG9neSIgfiAiT3Ntb3JlZ3VsYXRpb24sIE90aGVyIiwgIA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIlJlc3RpbmcgbWVtYnJhbmUgcG90ZW50aWFsIiB+ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZSBhbmQgcHJlZmVyZW5jZSIsICANCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJSZXByb2R1Y3Rpb24sIERldmVsb3BtZW50LCBsb25nZXZpdHkiIH4gIlJlcHJvZHVjdGlvbiwgRGV2ZWxvcG1lbnQsIEVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJSZXByb2R1Y3Rpb24sIERldmVsb3BtZW50LCBtb3J0YWxpdHkiIH4gIlJlcHJvZHVjdGlvbiwgRGV2ZWxvcG1lbnQsIEVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtLCBJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5LCBtZW1icmFuZSBwb3RlbnRpYWwiIH4gIkVuZXJnZXRpY3MgYW5kIG1ldGFib2xpc20sIEltbXVuZSBmdW5jdGlvbiBhbmQgc3RyZXNzIHBoeXNpb2xvZ3kiLA0KICAgICAgVHJhaXRfY2F0ZWdvcnkgPT0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlLCBtZW1icmFuZSBwb3RlbnRpYWwiIH4gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlIiwNCiAgICAgIFRyYWl0X2NhdGVnb3J5ID09ICJPc21vcmVndWxhdGlvbiwgbWVtYnJhbmUgcG90ZW50aWFsIiB+ICJPc21vcmVndWxhdGlvbiwgRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSIsDQogICAgICBUcmFpdF9jYXRlZ29yeSA9PSAiRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSwgbWVtYnJhbmUgcG90ZW50aWFsIiB+ICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiwgDQogICAgICBUUlVFIH4gVHJhaXRfY2F0ZWdvcnkNCiAgICApKQ0KDQojIENoZWNrIHVuaXF1ZSBjYXRlZ29yaWVzDQogZGF0YSAlPiUNCiAgcHVsbChUcmFpdF9jYXRlZ29yeSkgJT4lICAgICAgIA0KICBzdHJzcGxpdCgiLCAiKSAlPiUgICAgICAgICAgICAgICAgICAgIA0KICB1bmxpc3QoKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgdW5pcXVlKCkgIyBBbGwgZ29vZA0KDQojIFZpZXcgc3RyZXNzb3IgY2F0ZWdvcmllcw0KI1ZpZXcoZGF0YS5mcmFtZSh0YWJsZShkYXRhJENsaW1hdGVfY2hhbmdlX3N0cmVzc29yKSkpDQoNCiMgRGVsZXRlIGFuZCByZW5hbWUgc29tZSBvYnNlcnZhdGlvbnMgZm9yIGVudmlyb25tZW50YWwgc3RyZXNzb3JzDQpkYXRhIDwtIGRhdGEgJT4lIA0KICBmaWx0ZXIoQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgIT0gInByZXNzdXJlIGV4cG9zdXJlIiwNCiAgICAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yICE9ICJJbnRlcmFjdGlvbiB3aXRoIG5vbi1jbGltYXRpYyBzdHJlc3NvciIpICU+JSANCiAgbXV0YXRlKENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID0gY2FzZV93aGVuKA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIkFjaWRpZmljYXRpb24iIH4gInBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJhbHRpdHVkZSIgfiAiT+KCgi9DT+KCgiIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiQ2FsY2l1bSBjb250ZW50IiB+ICJwSCIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiQ08yIiB+ICJP4oKCL0NP4oKCIiwgDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiZGlldCIgfiAiT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJEaWV0IiB+ICJPdGhlciIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiZGlldCBhbmQgd2F0ZXIiIH4gIk90aGVyLCBIdW1pZGl0eS9XYXRlciBhdmFpbGFiaWxpdHkiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJIdW1pZGl0eSIgfiAiSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJIeXBlcmNhcG5pYSIgfiAiT+KCgi9DT+KCgiIsIA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIkludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yLCB3YXRlciByZXN0cmljdGlvbiIgfiAiSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IsIEh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAib3Ntb2xhbGl0eSIgfiAiU2FsaW5pdHkiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIGFjaWRpZmljYXRpb24iIH4gIk/igoIvQ0/igoIsIHBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIEFjaWRpZmljYXRpb24iIH4gIk/igoIvQ0/igoIsIHBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIGFsdGl0dWRlIiB+ICJP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIGNhcmJvbiBkaW94aWRlIiB+ICJP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4iIH4gIk/igoIvQ0/igoIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgQ08yIiB+ICJP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIEh1bWlkaXR5IiB+ICJP4oKCL0NP4oKCLCBIdW1pZGl0eS9XYXRlciBhdmFpbGFiaWxpdHkiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgcEgsIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiB+ICJP4oKCL0NP4oKCLCBJbnRlcmFjdGlvbiB3aXRoIG5vbi1jbGltYXRpYyBzdHJlc3NvciwgcEgiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgaHlwZXJjYXBuaWEiIH4gIk/igoIvQ0/igoIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IiIH4gIk/igoIvQ0/igoIsIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIGxpZ2h0IiB+ICJP4oKCL0NP4oKCLCBJbnRlcmFjdGlvbiB3aXRoIG5vbi1jbGltYXRpYyBzdHJlc3NvciIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiT3h5Z2VuLCBwSCIgfiAiT+KCgi9DT+KCgiwgcEgiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgcEgsIGFjaWRpZmljYXRpb24iIH4gIk/igoIvQ0/igoIsIHBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJPeHlnZW4sIHBILCBjYXJib24gZGlveGlkZSIgfiAiT+KCgi9DT+KCgiwgcEgiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIk94eWdlbiwgU2FsaW5pdHkiIH4gIk/igoIvQ0/igoIsIFNhbGluaXR5IiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJwSCwgYWNpZGlmaWNhdGlvbiIgfiAicEgiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gInBILCBBY2lkaWZpY2F0aW9uIiB+ICJwSCIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAicEgsIEFsdW1pbnVtIHRveGljaXR5IiB+ICJwSCwgSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gInBILCBIeXBlcmNhcG5pYSIgfiAiT+KCgi9DT+KCgiwgcEgiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gInBILCBTYWxpbml0eSwgQ08yIiB+ICJP4oKCL0NP4oKCLCBwSCwgU2FsaW5pdHkiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gInBILCBzYWx0IGFuZCBhbW1vbmlhIiB+ICJwSCwgU2FsaW5pdHksIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJwcmVjaXBpdGF0aW9uOiByYWlueSB2cyBkcnkiIH4gIkh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiU2FsaW5pdHksIGRlc3NpY2F0aW9uIiB+ICJTYWxpbml0eSwgSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgYWNpZGlmaWNhdGlvbiIgfiAiVGVtcGVyYXR1cmUsIHBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgQWNpZGlmaWNhdGlvbiIgfiAiVGVtcGVyYXR1cmUsIHBIIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgQXJ0aWZpY2lhbCBsaWdodCIgfiAiVGVtcGVyYXR1cmUsIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgQ2FyYm9uIERpb3hpZGUiIH4gIlRlbXBlcmF0dXJlLCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgQ08yIiB+ICJUZW1wZXJhdHVyZSwgT+KCgi9DT+KCgiIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIGRlaHlkcmF0aW9uIiB+ICJUZW1wZXJhdHVyZSwgSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgZGVzaWNjYXRpb24iIH4gIlRlbXBlcmF0dXJlLCBIdW1pZGl0eS9XYXRlciBhdmFpbGFiaWxpdHkiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBEaWV0IiB+ICJUZW1wZXJhdHVyZSwgT3RoZXIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBmb29kIHJlc3RyaWN0aW9uIiB+ICJUZW1wZXJhdHVyZSwgT3RoZXIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBmb29kIHNjYXJjaXR5IiB+ICJUZW1wZXJhdHVyZSwgT3RoZXIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBIdW1pZGl0eSIgfiAiVGVtcGVyYXR1cmUsIEh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIGxpbWl0ZWQgZm9vZCBhdmFpbGFiaWxpdHkiIH4gIlRlbXBlcmF0dXJlLCBPdGhlciIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIGxvdyB3YXRlciB2b2x1bWUiIH4gIlRlbXBlcmF0dXJlLCBIdW1pZGl0eS9XYXRlciBhdmFpbGFiaWxpdHkiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBPeHlnZW4iIH4gIlRlbXBlcmF0dXJlLCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgT3h5Z2VuLCBDTzIiIH4gIlRlbXBlcmF0dXJlLCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgT3h5Z2VuLCBIdW1pZGl0eSIgfiAiVGVtcGVyYXR1cmUsIEh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSwgT+KCgi9DT+KCgiIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIE94eWdlbiwgaHlwZXJjYXBuaWEiIH4gIlRlbXBlcmF0dXJlLCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgT3h5Z2VuLCBIeXBlcmNhcG5pYSIgfiAiVGVtcGVyYXR1cmUsIE/igoIvQ0/igoIiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBPeHlnZW4sIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiB+ICJUZW1wZXJhdHVyZSwgT+KCgi9DT+KCgiwgSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBPeHlnZW4sIFBDTzIiIH4gIlRlbXBlcmF0dXJlLCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgT3h5Z2VuLCBwSCIgfiAiVGVtcGVyYXR1cmUsIHBILCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgT3h5Z2VuLCBTYWxpbml0eSIgfiAiVGVtcGVyYXR1cmUsIFNhbGluaXR5LCBP4oKCL0NP4oKCIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgcEgsIGFjaWRpZmljYXRpb24iIH4gIlRlbXBlcmF0dXJlLCBwSCIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIHBob3RvcGVyaW9kIiB+ICJUZW1wZXJhdHVyZSwgSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCBVViIgfiAiVGVtcGVyYXR1cmUsIE90aGVyIiwgDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVGVtcGVyYXR1cmUsIFVWLUIgcmFkaWF0aW9uIiB+ICJUZW1wZXJhdHVyZSwgT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgVVYgcmFkaWF0aW9uIiB+ICJUZW1wZXJhdHVyZSwgT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJUZW1wZXJhdHVyZSwgd2F0ZXIgcmVzdHJpY3Rpb24iIH4gIlRlbXBlcmF0dXJlLCBIdW1pZGl0eS9XYXRlciBhdmFpbGFiaWxpdHkiLA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlLCB3YXZlIGFjdGlvbiIgfiAiVGVtcGVyYXR1cmUsIEludGVyYWN0aW9uIHdpdGggbm9uLWNsaW1hdGljIHN0cmVzc29yIiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJVbHRyYXZpb2xldCBCIHJhZGlhdGlvbiAoVVYtQikiIH4gIk90aGVyIiwgDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAiVVYtQiIgfiAiT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJVViIgfiAiT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJVVi1CIGV4cG9zdXJlIiB+ICJPdGhlciIsIA0KICAgICAgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlVWIHJhZGlhdGlvbiIgfiAiT3RoZXIiLCANCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJ3YXRlciIgfiAiSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiwNCiAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yID09ICJXYXRlciBhdmFpbGFiaWxpdHkiIH4gIkh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAid2F0ZXIgZGVwcml2YXRpb24iIH4gIkh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciA9PSAid2F0ZXIgcmVzdHJpY3Rpb24iIH4gIkh1bWlkaXR5L1dhdGVyIGF2YWlsYWJpbGl0eSIsDQogICAgICBUUlVFIH4gQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3INCiAgICApKQ0KIyBEaWV0IGFuZCBVViByYWRpYXRpb24gd2VyZSBwb29sZWQgdG9nZXRoZXIgYXMgIk90aGVyIiBiZWNhdXNlIHRoZXkgd2VyZSByYXJlDQoNCiMgQ2hlY2sgdW5pcXVlIGNhdGVnb3JpZXMNCiBkYXRhICU+JQ0KICBwdWxsKENsaW1hdGVfY2hhbmdlX3N0cmVzc29yKSAlPiUgICAgICAgDQogIHN0cnNwbGl0KCIsICIpICU+JSAgICAgICAgICAgICAgICAgICAgDQogIHVubGlzdCgpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICB1bmlxdWUoKSAjIEFsbCBnb29kDQogDQogDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIA0KIyBWaWV3IGxpZmUgc3RhZ2UgZXhwb3NlZCBjYXRlZ29yaWVzDQojVmlldyhkYXRhLmZyYW1lKHRhYmxlKGRhdGEkTGlmZV9zdGFnZV9leHBvc2VkKSkpDQoNCiMgRGVsZXRlIGFuZCByZW5hbWUgc29tZSBvYnNlcnZhdGlvbnMuIEVhY2ggb2YgdGhlc2Ugd2VyZSBjaGVja2VkIG1hbnVhbGx5IGFuZCByZXNvbHZlZC4NCmRhdGEgPC0gZGF0YSAlPiUgDQogIG11dGF0ZShMaWZlX3N0YWdlX2V4cG9zZWQgPSBjYXNlX3doZW4oDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gImFkdWx0cyIgfiAiQWR1bHRzIiwNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiQWR1bHRzLCBVbmNsZWFyIiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiRW1icnlvcywgZ2FtZXRlcyBhbmQgZW1icnlvcy4iIH4gIkVtYnJ5b3MiLA0KICAgICAgTGlmZV9zdGFnZV9leHBvc2VkID09ICJFbWJyeW9zLCBMYXJ2YWUgb3IganV2ZW5pbGVzLCBBZHVsdHMsIDcgZ2VuZXJhdGlvbnMgZXhwb3NlZCB0byAyIGRpZmZlcmVudCB0ZW1wcyIgfiAiTWl4IChiZWZvcmUgYW5kIGFmdGVyIGhhdGNoaW5nKSIsDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gIkVtYnJ5b3MsIExhcnZhZSBvciBqdXZlbmlsZXMsIEFkdWx0cywgTWl4IChiZWZvcmUgYW5kIGFmdGVyIGhhdGNoaW5nKSIgfiAiTWl4IChiZWZvcmUgYW5kIGFmdGVyIGhhdGNoaW5nKSIsDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gIkVtYnJ5b3MsIG1heWJlIGFsc28ganV2ZW5pbGVzLiBJdCdzIHVuY2xlYXIgd2hlbiB0aGUgdGVtcGVyYXR1cmUgdHJlYXRtZW50IGVuZHMuIiB+ICJFbWJyeW9zLCBBZHVsdHMiLA0KICAgICAgTGlmZV9zdGFnZV9leHBvc2VkID09ICJleHBvc3VyZSB3YXMgYXQgYSBzaW5nbGUgdGltZSBwb2ludCwgYnV0IHBlcmZvcm1lZCBvbiBhIG1peHR1cmUgb2YganV2ZW5pbGVzIGFuZCBhZHVsdHMgZm9yIHRoZSBvbmUgZXhwZXJpbWVudCIgfiAiTWl4IChzdHJpY3RseSBhZnRlciBoYXRjaGluZykiLA0KICAgICAgTGlmZV9zdGFnZV9leHBvc2VkID09ICJpdCBpcyBvbmUgZXhwb3N1cmUsIG9jY3VycmluZyBhdCBhIHNpbmdsZSB0aW1lIHBvaW50LCBidXQgc29tZSBvZiB0aGUgaW5kaXZpZHVhbHMgd2VyZSBhZHVsdCBhbmQgc29tZSB3ZXJlIGp1dmVuaWxlLiIgfiAiTWl4IChzdHJpY3RseSBhZnRlciBoYXRjaGluZykiLA0KICAgICAgTGlmZV9zdGFnZV9leHBvc2VkID09ICJMYXJ2YWUgb3IganV2ZW5pbGVzLCBhZHVsdHMiIH4gIkxhcnZhZSBvciBqdXZlbmlsZXMsIEFkdWx0cyIsDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gIkxhcnZhZSBvciBqdXZlbmlsZXMsIEFnZS0wIChjb3VsZCBiZSBqdXZlbmlsZXMgb3IgYWR1bHRzKSIgfiAiTGFydmFlIG9yIGp1dmVuaWxlcyIsICMgYWxsIHNwZWNpZXMgYXJlIG5vdCBzZXh1YWxseSBtYXR1cmUgYXQgdGhpcyBhZ2UNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiTGFydmFlIG9yIGp1dmVuaWxlcywgZXhwb3N1cmUgd2FzIHBlcmZvcm1lZCBvbiBsYXJ2YWUgb25seSBidXQgZm9yIDEzIGNvbnNlY3V0aXZlIGdlbmVyYXRpb25zIiB+ICJMYXJ2YWUgb3IganV2ZW5pbGVzIiwNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiU3ViYWR1bHQiIH4gIkxhcnZhZSBvciBqdXZlbmlsZXMiLCAjIFN1YiBhZHVsdHMgY2FuIGJlIGNvbnNpZGVyZWQganV2ZW5pbGVzDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gIlVuY2xlYXIsIDQgbW9udGggb2xkIG1hbGUgcmF0cyIgfiAiQWR1bHRzIiwgIyBUaGV5IGFyZSBzZXh1YWxseSBtYXR1cmUgYXQgdGhpcyBhZ2UNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiVW5jbGVhciwgRWl0aGVyIGp1dmVuaWxlcywgYWR1bHRzLCBvciBhIG1peHR1cmUgb2YgYm90aCBzdGFnZXMuIENhbid0IGVhc2lseSBkZXRlcm1pbmUgaXQuIiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiVW5jbGVhciwgSSBjYW4gaW5mZXIgaXRzIHBvc3QtaGF0Y2hpbmcsIGJ1dCBjYW5ub3Qgc2F5IHdpdGggY2VydGFpbnR5IHdoZXRoZXIgdGhleSdyZSBqdXZlbmlsZXMgb3IgYWR1bHRzLiIgfiAiVW5jbGVhciIsDQogICAgICBMaWZlX3N0YWdlX2V4cG9zZWQgPT0gIlVuY2xlYXIsIEkgdGhpbmsgaXQgaXMgZWl0aGVyIGp1dmVuaWxlIG9yIGFkdWx0IGJ1dCB0aGV5IGRvbid0IHNwZWNpZnkiIH4gIlVuY2xlYXIiLA0KICAgICAgTGlmZV9zdGFnZV9leHBvc2VkID09ICJVbmNsZWFyLCBwcm9iYWJseSBqdXZlbmlsZXMgb3IgYWR1bHRzIiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfZXhwb3NlZCA9PSAiQWR1bHRzLCBDb2xvbmlhbCBvcmdhbmlzbXMuIEluY2x1ZGVkIGdyYXZpZCByZXByb2R1Y3RpdmUgem9vaWRzIGJ1dCBhbHNvIGluY29tcGxldGUgem9vaWRzIiB+ICJNaXggKHN0cmljdGx5IGFmdGVyIGhhdGNoaW5nKSIsDQogICAgICBUUlVFIH4gTGlmZV9zdGFnZV9leHBvc2VkDQogICAgKSkNCg0KIGRhdGEgJT4lDQogIHB1bGwoTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUgICAgICAgDQogIHN0cnNwbGl0KCIsICIpICU+JSAgICAgICAgICAgICAgICAgICAgDQogIHVubGlzdCgpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICB1bmlxdWUoKSAjIEFsbCBnb29kLiANCiANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogDQojIFZpZXcgbGlmZSBzdGFnZSB0ZXN0ZWQgY2F0ZWdvcmllcw0KI1ZpZXcoZGF0YS5mcmFtZSh0YWJsZShkYXRhJExpZmVfc3RhZ2VfdGVzdGVkKSkpDQogDQojIERlbGV0ZSBhbmQgcmVuYW1lIHNvbWUgb2JzZXJ2YXRpb25zIGZvciBsaWZlIHN0YWdlcw0KZGF0YSA8LSBkYXRhICU+JSANCiAgbXV0YXRlKExpZmVfc3RhZ2VfdGVzdGVkID0gY2FzZV93aGVuKA0KICAgICAgTGlmZV9zdGFnZV90ZXN0ZWQgPT0gImFkdWx0cyIgfiAiQWR1bHRzIiwNCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJBZHVsdHMsIENvbG9uaWFsIG9yZ2FuaXNtcy4gSW5jbHVkZWQgZ3JhdmlkIHJlcHJvZHVjdGl2ZSB6b29pZHMgYnV0IGFsc28gaW5jb21wbGV0ZSB6b29pZHMiIH4gIkFkdWx0cywgTGFydmFlIG9yIGp1dmVuaWxlcyIsDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiQWR1bHRzLCBQcm9nZW55IG9mIHRoZXNlIGFkdWx0cyB0aGF0IHdlcmUgZXhwb3NlZCB0byBkaWZmIHRlbXBlcmF0dXJlIGFzIGVtYnJ5b3MgKEYyKSIgfiAiQWR1bHRzLCBMYXJ2YWUgb3IganV2ZW5pbGVzIiwNCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJBZHVsdHMsIFVuY2xlYXIiIH4gIlVuY2xlYXIiLA0KICAgICAgTGlmZV9zdGFnZV90ZXN0ZWQgPT0gIkFkdWx0cywgdW5mZXJ0aWxpemVkIGVnZ3MiIH4gIkFkdWx0cyIsDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiYW5hbHlzaXMgaXMgb24gaG9tb2dlbmF0ZXMgZ2VuZXJhdGVkIGZyb20gbXVsdGlwbGUgaW5kaXZpZHVhbHMgbGlrZWx5IHNwYW5uaW5nIGFsbCBsaWZlLXN0YWdlcy4iIH4gIkFkdWx0cywgTGFydmFlIG9yIGp1dmVuaWxlcyIsDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiRW1icnlvcywgTGFydmFlIGFuZCBqdXZlbmlsZXMiIH4gIkVtYnJ5b3MsIExhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgTGlmZV9zdGFnZV90ZXN0ZWQgPT0gImV4cG9zdXJlIHdhcyBhdCBhIHNpbmdsZSB0aW1lIHBvaW50LCBidXQgcGVyZm9ybWVkIG9uIGEgbWl4dHVyZSBvZiBqdXZlbmlsZXMgYW5kIGFkdWx0cyBmb3IgdGhlIG9uZSBleHBlcmltZW50IiB+ICJBZHVsdHMsIExhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgTGlmZV9zdGFnZV90ZXN0ZWQgPT0gIml0IGlzIG9uZSBleHBlcmltZW50LCBvY2N1cnJpbmcgYXQgYSBzaW5nbGUgdGltZSBwb2ludCwgYnV0IHNvbWUgb2YgdGhlIGluZGl2aWR1YWxzIHdlcmUgYWR1bHQgYW5kIHNvbWUgd2VyZSBqdXZlbmlsZS4iIH4gIkFkdWx0cywgTGFydmFlIG9yIGp1dmVuaWxlcyIsDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiTGFydmFlIG9yIGp1dmVuaWxlcywgYWR1bHRzIiB+ICJMYXJ2YWUgb3IganV2ZW5pbGVzLCBBZHVsdHMiLCANCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJMYXJ2YWUgb3IganV2ZW5pbGVzLCBBZ2UtMCAoY291bGQgYmUganV2ZW5pbGVzIG9yIGFkdWx0cykiIH4gIkxhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgTGlmZV9zdGFnZV90ZXN0ZWQgPT0gIlN1YmFkdWx0IiB+ICJMYXJ2YWUgb3IganV2ZW5pbGVzIiwgDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiVW5jbGVhciwgNCBtb250aHMgb2xkIG1hbGUgcmF0cyIgfiAiQWR1bHRzIiwgDQogICAgICBMaWZlX3N0YWdlX3Rlc3RlZCA9PSAiVW5jbGVhciwgRWl0aGVyIGp1dmVuaWxlcywgYWR1bHRzLCBvciBhIG1peHR1cmUgb2YgYm90aCBzdGFnZXMuIENhbid0IGVhc2lseSBkZXRlcm1pbmUgaXQuIiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJVbmNsZWFyLCBJIGNhbiBpbmZlciBpdHMgcG9zdC1oYXRjaGluZywgYnV0IGNhbm5vdCBzYXkgd2l0aCBjZXJ0YWludHkgd2hldGhlciB0aGV5J3JlIGp1dmVuaWxlcyBvciBhZHVsdHMuIiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJVbmNsZWFyLCBJIHRoaW5rIGl0IGlzIGVpdGhlciBqdXZlbmlsZSBvciBhZHVsdCBidXQgdGhleSBkb24ndCBzcGVjaWZ5IiB+ICJVbmNsZWFyIiwNCiAgICAgIExpZmVfc3RhZ2VfdGVzdGVkID09ICJVbmNsZWFyLCBwcm9iYWJseSBqdXZlbmlsZSBvciBhZHVsdHMiIH4gIlVuY2xlYXIiLA0KICAgICAgVFJVRSB+IExpZmVfc3RhZ2VfdGVzdGVkDQogICAgKSkNCg0KIGRhdGEgJT4lDQogIHB1bGwoTGlmZV9zdGFnZV90ZXN0ZWQpICU+JSAgICAgICANCiAgc3Ryc3BsaXQoIiwgIikgJT4lICAgICAgICAgICAgICAgICAgICANCiAgdW5saXN0KCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIHVuaXF1ZSgpICMgQWxsIGdvb2QuICAgDQpgYGANCg0KIyAqKlNhdmUgcHJvY2Vzc2VkIGRhdGEgYW5kIGNpdGF0aW9uIGluZm9ybWF0aW9uKiogDQoNCmBgYHtyfQ0KIyBSZWFkIGZpbGVzIHdpdGggYmlibGlvZ3JhcGhpYyBpbmZvcm1hdGlvbiBwcmlvciB0byBzY3JlZW5pbmcNCmJpYiA8LSByZWFkX2NzdigiQmlibGlvZ3JhcGhpY19zZWFyY2hlcy9hbGxfYmlibGlvZ3JhcGhpY19yZWNvcmRzLmNzdiIpDQpiaWIgPC0gYmliICU+JSByZW5hbWUoRE9JID0gZG9pKQ0KDQojIExlZnQgam9pbiB0aGUgZmlsZXMgdG8gb25seSBrZWVwIHRoZSBpbmNsdWRlZCBzdHVkaWVzDQppbmNsdWRlZF9zdHVkaWVzIDwtIGxlZnRfam9pbihkYXRhLCBiaWIsIGJ5PSJET0kiKQ0KDQppbmNsdWRlZF9zdHVkaWVzIDwtIGluY2x1ZGVkX3N0dWRpZXMgJT4lIA0KICBkcGx5cjo6c2VsZWN0KHRpdGxlLCBhdXRob3JzLCBqb3VybmFsLCBET0ksIGFic3RyYWN0LCB5ZWFyLCB2b2x1bWUsIGlzc3VlLCBwYWdlcykNCg0KIyBTYXZlIGJpYmxpb2dyYXBoaWMgZmlsZQ0Kd3JpdGVfY3N2KGluY2x1ZGVkX3N0dWRpZXMsIGZpbGUgPSAiQmlibGlvZ3JhcGhpY19zZWFyY2hlcy9hbGxfaW5jbHVkZWRfc3R1ZGllcy5jc3YiKQ0KDQojIFNhdmUgcHJvY2Vzc2VkIGRhdGEgDQpkYXRhIDwtIGRhdGEgJT4lIA0KICBkcGx5cjo6c2VsZWN0KFNob3J0X3JlZmVyZW5jZSwgUHVibGljYXRpb25feWVhciwgVGl0bGUsIERPSSwgSm91cm5hbCwgVGF4b25vbWljX2dyb3VwLCBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciwgTGlmZV9zdGFnZV9leHBvc2VkLCBMaWZlX3N0YWdlX3Rlc3RlZCwgVHJhaXRfY2F0ZWdvcnksIFRyYWl0X2RldGFpbHMsIEFkZGl0aW9uYWxfY29tbWVudHMpDQoNCndyaXRlX2NzdihkYXRhLCBmaWxlID0gIkRhdGEvY2xlYW5lZF9kYXRhLmNzdiIpDQpgYGANCg0KDQoNCiMgKipPdmVyYWxsIGRhdGEgc3VtbWFyeSoqIHsudGFic2V0IC50YWJzZXRfZmFkZSAudGFic2V0X3BpbGxzfQ0KDQpUaGUgbnVtYmVycyBiZWxvdyByZXByZXNlbnQgdGhlIG51bWJlciBvZiBzdHVkaWVzIGZyb20gZGlmZmVyZW50IGpvdXJuYWxzLCB0cmFpdCBjYXRlZ29yaWVzLCBjbGltYXRpYyBzdHJlc3NvcnMsIHRheGEsIGFuZCBsaWZlIHN0YWdlcyAoZXhwb3NlZCB0byB0aGUgY2xpbWF0aWMgc3RyZXNzb3IsIG9yIGFzc2Vzc2VkIGZvciBwaHlzaW9sb2dpY2FsIHRyYWl0cykuDQpOb3RlIHRoYXQgYmVjYXVzZSBzb21lIHN0dWRpZXMgaGF2ZSBpbnZlc3RpZ2F0ZWQgbXVsdGlwbGUgdHJhaXRzLCBzdHJlc3NvcnMsIHRheGEsIGFuZCBsaWZlIHN0YWdlcywgdGhlIG51bWJlcnMgZG8gbm90IGFkZCB0byB0aGUgdG90YWwgbnVtYmVyIG9mIHN0dWRpZXMgKG4gPSAxMjQ1KS4gDQoNCiMjICoqSm91cm5hbHMqKiANCg0KYGBge3J9DQojIE51bWJlciBvZiBzdHVkaWVzIHBlciBqb3VybmFsDQpqb3VybmFsX3N1bW1hcnkgPC0gZGF0YSAlPiUgDQogIHB1bGwoSm91cm5hbCkgJT4lIA0KICB0YWJsZSgpICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JSANCiAgcmVuYW1lKGBKb3VybmFsYCA9ICIuIiwgbiA9ICJGcmVxIikgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gKG4gLyBzdW0obikpKjEwMCkgJT4lDQogIGFycmFuZ2UocGVyY2VudGFnZSkNCg0KZmxleHRhYmxlKGpvdXJuYWxfc3VtbWFyeSkgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIkpvdXJuYWxzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKSAgIyAxODEgZnJvbSBDb25zIFBoeXMsIDU2MiBmcm9tIEpFQiwgNTMzIGZyb20gSlRCLg0KDQojIFRvdGFsIG51bWJlciBvZiBzdHVkaWVzDQpuX2Rpc3RpbmN0KGRhdGEkRE9JKSAjIDEyNzYgc3R1ZGllcw0KYGBgDQoNCiMjICoqVHJhaXQgY2F0ZWdvcmllcyoqIA0KDQpgYGB7cn0NCiMgVHJhaXRzDQp0cmFpdF9zdW1tYXJ5IDwtIGRhdGEgJT4lDQogIHB1bGwoVHJhaXRfY2F0ZWdvcnkpICU+JQ0KICBzdHJzcGxpdCgiLCAiKSAlPiUNCiAgdW5saXN0KCkgJT4lDQogIHRhYmxlKCkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgcmVuYW1lKGBUcmFpdCBjYXRlZ29yeWAgPSAiLiIsIG4gPSAiRnJlcSIpICU+JQ0KICBtdXRhdGUocGVyY2VudGFnZSA9IChuIC8gc3VtKG4pKSoxMDApICU+JQ0KICBhcnJhbmdlKGRlc2MocGVyY2VudGFnZSkpDQoNCmZsZXh0YWJsZSh0cmFpdF9zdW1tYXJ5KSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiVHJhaXQgY2F0ZWdvcmllcyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCmBgYA0KDQojIyAqKlRheG9ub21pYyBncm91cHMqKg0KDQpgYGB7cn0NCiMgVGF4YQ0KdGF4YV9zdW1tYXJ5IDwtIGRhdGEgJT4lDQogIHB1bGwoVGF4b25vbWljX2dyb3VwKSAlPiUNCiAgc3Ryc3BsaXQoIiwgIikgJT4lDQogIHVubGlzdCgpICU+JQ0KICB0YWJsZSgpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIHJlbmFtZShgVGF4b25vbWljIGdyb3VwYCA9ICIuIiwgbiA9ICJGcmVxIikgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gKG4gLyBzdW0obikpKjEwMCkgJT4lDQogIGFycmFuZ2UoZGVzYyhwZXJjZW50YWdlKSkNCg0KZmxleHRhYmxlKHRheGFfc3VtbWFyeSkgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIlRheG9ub21pYyBncm91cHMiKSAlPiUgIA0KICBiZyhiZyA9ICJ3aGl0ZSIsIHBhcnQgPSAiYWxsIikgJT4lICANCiAgY29sb3IoY29sb3IgPSAiYmxhY2siLCBwYXJ0ID0gImFsbCIpDQpgYGANCg0KIyMgKipDbGltYXRlIGNoYW5nZSBzdHJlc3NvcnMqKg0KDQpgYGB7cn0NCiMgU3RyZXNzb3JzDQpzdHJlc3Nvcl9zdW1tYXJ5IDwtIGRhdGEgJT4lDQogIHB1bGwoQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IpICU+JQ0KICBzdHJzcGxpdCgiLCAiKSAlPiUNCiAgdW5saXN0KCkgJT4lDQogIHRhYmxlKCkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUNCiAgcmVuYW1lKGBDbGltYXRpYyBzdHJlc3NvcmAgPSAiLiIsIG4gPSAiRnJlcSIpICU+JQ0KICBtdXRhdGUocGVyY2VudGFnZSA9IChuIC8gc3VtKG4pKSoxMDApICU+JQ0KICBhcnJhbmdlKGRlc2MocGVyY2VudGFnZSkpDQoNCmZsZXh0YWJsZShzdHJlc3Nvcl9zdW1tYXJ5KSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiQ2xpbWF0ZSBjaGFuZ2Ugc3RyZXNzb3JzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KDQoNCiMgQWZ0ZXIgcmVtb3Zpbmcgc3R1ZGllcyBmcm9tIHRoZSBKb3VybmFsIG9mIFRoZXJtYWwgQmlvbG9neSAod2hpY2ggaXMgbGFyZ2VseSBmb2N1c2luZyBvbiB0ZW1wZXJhdHVyZSkNCnN0cmVzc29yX3N1bW1hcnlfanRiIDwtIGRhdGEgJT4lDQogIGZpbHRlcihKb3VybmFsICE9ICJKb3VybmFsIG9mIFRoZXJtYWwgQmlvbG9neSIpICU+JSANCiAgcHVsbChDbGltYXRlX2NoYW5nZV9zdHJlc3NvcikgJT4lDQogIHN0cnNwbGl0KCIsICIpICU+JQ0KICB1bmxpc3QoKSAlPiUNCiAgdGFibGUoKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICByZW5hbWUoYENsaW1hdGVfc3RyZXNzb3JgID0gIi4iLCBuID0gIkZyZXEiKSAlPiUNCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSAobiAvIHN1bShuKSkqMTAwKSAlPiUNCiAgYXJyYW5nZShwZXJjZW50YWdlKQ0KDQpmbGV4dGFibGUoc3RyZXNzb3Jfc3VtbWFyeV9qdGIpICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJDbGltYXRlIGNoYW5nZSBzdHJlc3NvcnMiKSAlPiUgIA0KICBiZyhiZyA9ICJ3aGl0ZSIsIHBhcnQgPSAiYWxsIikgJT4lICANCiAgY29sb3IoY29sb3IgPSAiYmxhY2siLCBwYXJ0ID0gImFsbCIpDQpgYGANCg0KIyMgKipMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yKiogDQpgYGB7cn0NCiMgTGlmZSBzdGFnZSBleHBvc2VkIHRvIHRoZSBjbGltYXRpYyBzdHJlc3Nvcg0KbHNfZXhwb3NlZF9zdW1tYXJ5IDwtIGRhdGEgJT4lDQogIHB1bGwoTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUNCiAgc3Ryc3BsaXQoIiwgIikgJT4lDQogIHVubGlzdCgpICU+JQ0KICB0YWJsZSgpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lDQogIHJlbmFtZShgTGlmZSBzdGFnZSBleHBvc2VkYCA9ICIuIiwgbiA9ICJGcmVxIikgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gKG4gLyBzdW0obikpKjEwMCkgJT4lDQogIGFycmFuZ2UoZGVzYyhwZXJjZW50YWdlKSkNCg0KZmxleHRhYmxlKGxzX2V4cG9zZWRfc3VtbWFyeSkgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIkxpZmUgc3RhZ2VzIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCiMjICoqTGlmZSBzdGFnZSBhc3Nlc3NlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMqKiANCg0KYGBge3J9DQojIExpZmUgc3RhZ2UgdGVzdGVkIGZvciBwaHlzaW9sb2dpY2FsIHRyYWl0cw0KbHNfdGVzdGVkX3N1bW1hcnkgPC0gZGF0YSAlPiUNCiAgcHVsbChMaWZlX3N0YWdlX3Rlc3RlZCkgJT4lDQogIHN0cnNwbGl0KCIsICIpICU+JQ0KICB1bmxpc3QoKSAlPiUNCiAgdGFibGUoKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JQ0KICByZW5hbWUoYExpZmUgc3RhZ2UgdGVzdGVkYCA9ICIuIiwgbiA9ICJGcmVxIikgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gKG4gLyBzdW0obikpKjEwMCkgJT4lDQogIGFycmFuZ2UoZGVzYyhwZXJjZW50YWdlKSkNCg0KZmxleHRhYmxlKGxzX3Rlc3RlZF9zdW1tYXJ5KSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgYXNzZXNzZWQgZm9yIHBoeXNpb2xvZ2ljYWwgdHJhaXRzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCg0KDQojICoqRGF0YSBzdW1tYXJ5IGJ5IGxpZmUgc3RhZ2UgKGV4cG9zZWQgdG8gY2xpbWF0aWMgc3RyZXNzb3JzKSoqIHsudGFic2V0IC50YWJzZXRfZmFkZSAudGFic2V0X3BpbGxzfQ0KDQpIZXJlLCBkYXRhIHN1bW1hcmllcyBhcmUgZ2VuZXJhdGVkIHNlcGFyYXRlbHkgZm9yIGVhY2ggbGlmZSBzdGFnZS4gDQpJbiB0aGlzIHN0dWR5LCB3ZSBkaWZmZXJlbnRpYXRlZCB0aGUgbGlmZSBzdGFnZXMgZXhwb3NlZCB0byBjbGltYXRpYyBzdHJlc3NvcnMgKHByZXNlbnRlZCBoZXJlKSwgdG8gdGhvc2UgYXNzZXNzZWQgZm9yIHBoeXNpb2xvZ2ljYWwgc3RyZXNzb3JzIChwcmVzZW50ZWQgZnVydGhlciBiZWxvdyksIGFzIHRoZXNlIHNvbWV0aW1lcyBkaWZmZXIsIGVzcGVjaWFsbHkgaW4gdGhlIGNvbnRleHQgb2YgbG9uZ2l0dWRpbmFsIHN0dWRpZXMuIA0KDQojIyAqKkhlbHBlciBmdW5jdGlvbioqDQpgYGB7cn0NCiMgSGVscGVyIGZ1bmN0aW9uIGZvciBzcGxpdHRpbmcgKyB1bm5lc3RpbmcgbGlmZSBzdGFnZXMNCnNwbGl0X2FuZF9zdW1tYXJpc2UgPC0gZnVuY3Rpb24oZGF0YSwgZ3JvdXBfdmFyKSB7DQogIGxpZmVfc3RhZ2Vfb3JkZXIgPC0gYygiVW5jbGVhciIsICJNaXggKHN0cmljdGx5IGFmdGVyIGhhdGNoaW5nKSIsICJNaXggKGJlZm9yZSBhbmQgYWZ0ZXIgaGF0Y2hpbmcpIiwgIkVtYnJ5b3MiLCAiTGFydmFlIG9yIGp1dmVuaWxlcyIsICJBZHVsdHMiKQ0KICBkYXRhICU+JQ0KICAgIG11dGF0ZShhY3Jvc3MoYWxsX29mKGMoIkxpZmVfc3RhZ2VfZXhwb3NlZCIsIGdyb3VwX3ZhcikpLCB+IHN0cnNwbGl0KGFzLmNoYXJhY3RlciguKSwgIiwgIikpKSAlPiUNCiAgICB1bm5lc3QoTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUNCiAgICB1bm5lc3QoYWxsX29mKGdyb3VwX3ZhcikpICU+JQ0KICAgIG11dGF0ZShMaWZlX3N0YWdlX2V4cG9zZWQgPSBmYWN0b3IoTGlmZV9zdGFnZV9leHBvc2VkLCBsZXZlbHMgPSBsaWZlX3N0YWdlX29yZGVyKSkgJT4lDQogICAgY291bnQoISFzeW0oZ3JvdXBfdmFyKSwgTGlmZV9zdGFnZV9leHBvc2VkLCBuYW1lID0gIm4iKSAlPiUNCiAgICBncm91cF9ieSghIXN5bShncm91cF92YXIpKSAlPiUNCiAgICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0obikpICU+JQ0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgcmVuYW1lKGBMaWZlIHN0YWdlIGV4cG9zZWRgID0gTGlmZV9zdGFnZV9leHBvc2VkKQ0KfQ0KDQpgYGANCg0KDQojIyAqKkpvdXJuYWxzKiogDQoNCmBgYHtyfQ0KIyBMaWZlIHN0YWdlIGV4cG9zZWQgYnkgSm91cm5hbA0KbGlmZV9zdGFnZV9ieV9qb3VybmFsX2V4cCA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlKGRhdGEsICJKb3VybmFsIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfam91cm5hbF9leHApICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJMaWZlIHN0YWdlcyBleHBvc2VkIGFjcm9zcyBqb3VybmFscyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCmBgYA0KDQojIyAqKlRyYWl0IGNhdGVnb3JpZXMqKiANCg0KYGBge3J9DQojIExpZmUgc3RhZ2UgZXhwb3NlZCBieSBUcmFpdCBjYXRlZ29yeQ0KbGlmZV9zdGFnZV9ieV90cmFpdF9leHAgPC0gc3BsaXRfYW5kX3N1bW1hcmlzZShkYXRhLCAiVHJhaXRfY2F0ZWdvcnkiKQ0KDQpmbGV4dGFibGUobGlmZV9zdGFnZV9ieV90cmFpdF9leHApICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJMaWZlIHN0YWdlcyBleHBvc2VkIGFjcm9zcyB0cmFpdCBjYXRlZ29yaWVzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCiMjICoqVGF4b25vbWljIGdyb3VwcyoqDQoNCmBgYHtyfQ0KIyBMaWZlIHN0YWdlIGV4cG9zZWQgYnkgVGF4b25vbWljX2dyb3VwDQpsaWZlX3N0YWdlX2J5X3RheGFfZXhwIDwtIHNwbGl0X2FuZF9zdW1tYXJpc2UoZGF0YSwgIlRheG9ub21pY19ncm91cCIpDQoNCmZsZXh0YWJsZShsaWZlX3N0YWdlX2J5X3RheGFfZXhwKSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgZXhwb3NlZCBhY3Jvc3MgdGF4b25vbWljIGdyb3VwcyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCmBgYA0KDQojIyAqKkNsaW1hdGUgY2hhbmdlIHN0cmVzc29ycyoqDQoNCmBgYHtyfQ0KIyBMaWZlIHN0YWdlIGV4cG9zZWQgYnkgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3INCmxpZmVfc3RhZ2VfYnlfc3RyZXNzb3JfZXhwIDwtIHNwbGl0X2FuZF9zdW1tYXJpc2UoZGF0YSwgIkNsaW1hdGVfY2hhbmdlX3N0cmVzc29yIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfc3RyZXNzb3JfZXhwKSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgZXhwb3NlZCBhY3Jvc3MgY2xpbWF0ZSBjaGFuZ2Ugc3RyZXNzb3JzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCg0KIyAqKkRhdGEgc3VtbWFyeSBieSBsaWZlIHN0YWdlIChhc3Nlc3NlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMpKiogey50YWJzZXQgLnRhYnNldF9mYWRlIC50YWJzZXRfcGlsbHN9DQoNCkhlcmUsIGRhdGEgc3VtbWFyaWVzIGFyZSBnZW5lcmF0ZWQgc2VwYXJhdGVseSBmb3IgZWFjaCBsaWZlIHN0YWdlLiANCkluIHRoaXMgc3R1ZHksIHdlIGRpZmZlcmVudGlhdGVkIHRoZSBsaWZlIHN0YWdlcyBleHBvc2VkIHRvIGNsaW1hdGljIHN0cmVzc29ycyAocHJlc2VudGVkIGFib3ZlKSwgdG8gdGhvc2UgYXNzZXNzZWQgZm9yIHBoeXNpb2xvZ2ljYWwgc3RyZXNzb3JzIChwcmVzZW50ZWQgaGVyZSksIGFzIHRoZXNlIHNvbWV0aW1lcyBkaWZmZXIsIGVzcGVjaWFsbHkgaW4gdGhlIGNvbnRleHQgb2YgbG9uZ2l0dWRpbmFsIHN0dWRpZXMuDQoNCiMjICoqSGVscGVyIGZ1bmN0aW9uKioNCmBgYHtyfQ0KDQojIEhlbHBlciBmdW5jdGlvbiBmb3Igc3BsaXR0aW5nICsgdW5uZXN0aW5nIHRoZSBkaWZmZXJlbnQgbGlmZSBzdGFnZXMNCnNwbGl0X2FuZF9zdW1tYXJpc2UyIDwtIGZ1bmN0aW9uKGRhdGEsIGdyb3VwX3Zhcikgew0KICBsaWZlX3N0YWdlX29yZGVyIDwtIGMoIlVuY2xlYXIiLCAiRW1icnlvcyIsICJMYXJ2YWUgb3IganV2ZW5pbGVzIiwgIkFkdWx0cyIpDQogIGRhdGEgJT4lDQogICAgbXV0YXRlKGFjcm9zcyhhbGxfb2YoYygiTGlmZV9zdGFnZV90ZXN0ZWQiLCBncm91cF92YXIpKSwgfiBzdHJzcGxpdChhcy5jaGFyYWN0ZXIoLiksICIsICIpKSkgJT4lDQogICAgdW5uZXN0KExpZmVfc3RhZ2VfdGVzdGVkKSAlPiUNCiAgICB1bm5lc3QoYWxsX29mKGdyb3VwX3ZhcikpICU+JQ0KICAgIG11dGF0ZShMaWZlX3N0YWdlX3Rlc3RlZCA9IGZhY3RvcihMaWZlX3N0YWdlX3Rlc3RlZCwgbGV2ZWxzID0gbGlmZV9zdGFnZV9vcmRlcikpICU+JQ0KICAgIGNvdW50KCEhc3ltKGdyb3VwX3ZhciksIExpZmVfc3RhZ2VfdGVzdGVkLCBuYW1lID0gIm4iKSAlPiUNCiAgICBncm91cF9ieSghIXN5bShncm91cF92YXIpKSAlPiUNCiAgICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0obikpICU+JQ0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgcmVuYW1lKGBMaWZlIHN0YWdlIHRlc3RlZGAgPSBMaWZlX3N0YWdlX3Rlc3RlZCkNCn0NCmBgYA0KDQojIyAqKkpvdXJuYWxzKiogDQoNCmBgYHtyfQ0KIyBMaWZlX3N0YWdlX3Rlc3RlZCBieSBKb3VybmFsDQpsaWZlX3N0YWdlX2J5X2pvdXJuYWwgPC0gc3BsaXRfYW5kX3N1bW1hcmlzZTIoZGF0YSwgIkpvdXJuYWwiKQ0KDQpmbGV4dGFibGUobGlmZV9zdGFnZV9ieV9qb3VybmFsKSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgdGVzdGVkIGFjcm9zcyBqb3VybmFscyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCmBgYA0KDQojIyAqKlRyYWl0IGNhdGVnb3JpZXMqKiANCg0KYGBge3J9DQojIExpZmVfc3RhZ2VfdGVzdGVkIGJ5IFRyYWl0IGNhdGVnb3J5DQpsaWZlX3N0YWdlX2J5X3RyYWl0IDwtIHNwbGl0X2FuZF9zdW1tYXJpc2UyKGRhdGEsICJUcmFpdF9jYXRlZ29yeSIpDQoNCmZsZXh0YWJsZShsaWZlX3N0YWdlX2J5X3RyYWl0KSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgdGVzdGVkIGFjcm9zcyB0cmFpdCBjYXRlZ29yaWVzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCiMjICoqVGF4b25vbWljIGdyb3VwcyoqDQoNCmBgYHtyfQ0KIyBMaWZlX3N0YWdlX3Rlc3RlZCBieSBUYXhvbm9taWNfZ3JvdXANCmxpZmVfc3RhZ2VfYnlfdGF4YSA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlMihkYXRhLCAiVGF4b25vbWljX2dyb3VwIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfdGF4YSkgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIkxpZmUgc3RhZ2VzIHRlc3RlZCBhY3Jvc3MgdGF4b25vbWljIGdyb3VwcyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCmBgYA0KDQojIyAqKkNsaW1hdGUgY2hhbmdlIHN0cmVzc29ycyoqDQoNCmBgYHtyfQ0KIyBMaWZlX3N0YWdlX3Rlc3RlZCBieSBDbGltYXRlX2NoYW5nZV9zdHJlc3Nvcg0KbGlmZV9zdGFnZV9ieV9zdHJlc3NvciA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlMihkYXRhLCAiQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IiKQ0KDQpmbGV4dGFibGUobGlmZV9zdGFnZV9ieV9zdHJlc3NvcikgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIkxpZmUgc3RhZ2VzIHRlc3RlZCBhY3Jvc3MgY2xpbWF0ZSBjaGFuZ2Ugc3RyZXNzb3JzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KYGBgDQoNCg0KIyAqKkZpZ3VyZXMqKg0KDQpOb3RlIHRoYXQgYWxsIGZpZ3VyZXMgd2VyZSBjdXN0b21pc2VkIGluIElsbHVzdHJhdG9yIGZvciBjb3NtZXRpYyBwdXJwb3Nlcy4gDQoNCiMjICoqRmlndXJlIDEqKiANCg0KIyMjICoqQ29sb3VyIHBhbGV0dGVzIGFuZCB0aGVtZXMqKg0KDQpgYGB7cn0NCiMgQ3JlYXRhIGNvbG91ciBwYWxldHRlDQpwYWxldHRlIDwtIGMoDQogICJVbmNsZWFyIiA9ICJncmF5NzAiLCAgICAgICANCiAgIkVtYnJ5b3MiID0gIiNFNkFCMDIiLCAgICAgICANCiAgIkxhcnZhZSBvciBqdXZlbmlsZXMiID0gIiM3NTcwQjMiLCAgDQogICJBZHVsdHMiID0gIiMxQjlFNzciLA0KICAiTWl4IChiZWZvcmUgYW5kIGFmdGVyIGhhdGNoaW5nKSIgPSAiIzdEOTM2NCIsDQogICJNaXggKHN0cmljdGx5IGFmdGVyIGhhdGNoaW5nKSIgPSAiI0FFOEU1QiIpDQoNCiMgQ3JlYXRlIGN1c3RvbSB0aGVtZQ0KY3VzdG9tX3RoZW1lIDwtIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTQpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuNCksDQogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiwgaGp1c3QgPSAxLCBjb2xvciA9ICJibGFjayIpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk1LCAwLjA1KSwNCiAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgImJvdHRvbSIpLA0KICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEuMjUpKQ0KYGBgDQoNCg0KIyMjICoqVGVtcG9yYWwgdHJlbmRzKioNCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KYGBge3J9DQojIFByZXBhcmUgZGF0YSBmb3Igc3RyZWFtIHBsb3QgKHByb3BvcnRpb25zIGJ5IHllYXIgYW5kIGxpZmUgc3RhZ2UpDQpsc19leHBvc2VkX3N0cmVhbSA8LSBkYXRhICU+JQ0KICBzZWxlY3QoUHVibGljYXRpb25feWVhciwgTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUNCiAgbXV0YXRlKExpZmVfc3RhZ2VfZXhwb3NlZCA9IHN0cnNwbGl0KExpZmVfc3RhZ2VfZXhwb3NlZCwgIiwgIikpICU+JQ0KICB1bm5lc3QoTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUNCiAgZ3JvdXBfYnkoUHVibGljYXRpb25feWVhciwgTGlmZV9zdGFnZV9leHBvc2VkKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShQdWJsaWNhdGlvbl95ZWFyKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKG4pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoTGlmZV9zdGFnZV9leHBvc2VkID0gZmFjdG9yKA0KICAgIExpZmVfc3RhZ2VfZXhwb3NlZCwNCiAgICBsZXZlbHMgPSBjKA0KICAgICAgIkFkdWx0cyIsDQogICAgICAiTGFydmFlIG9yIGp1dmVuaWxlcyIsDQogICAgICAiRW1icnlvcyIsICAgICAgICAgICAgIA0KICAgICAgIk1peCAoYmVmb3JlIGFuZCBhZnRlciBoYXRjaGluZykiLA0KICAgICAgIk1peCAoc3RyaWN0bHkgYWZ0ZXIgaGF0Y2hpbmcpIiwNCiAgICAgICJVbmNsZWFyIg0KICAgICkNCiAgKSkNCg0KIyBDcmVhdGUgcGxvdA0Kc3RyZWFtX2xzX2V4cG9zZWQgPC0gZ2dwbG90KGRhdGEgPSBsc19leHBvc2VkX3N0cmVhbSwNCiAgICAgICBhZXMoeCA9IFB1YmxpY2F0aW9uX3llYXIsDQogICAgICAgICAgIHkgPSBwcm9wb3J0aW9uLA0KICAgICAgICAgICBmaWxsID0gTGlmZV9zdGFnZV9leHBvc2VkKSkgKw0KICBnZW9tX3N0cmVhbSh0eXBlID0gInByb3BvcnRpb24iLCBhbHBoYSA9IDAuNikgKw0KICBnZW9tX3N0cmVhbV9sYWJlbCh0eXBlID0gInJpZGdlIiwgYWVzKGxhYmVsID0gTGlmZV9zdGFnZV9leHBvc2VkKSwgc2l6ZSAgPSA3KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUpKyAgDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMSwgMC4yNSksDQogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApKSArDQogIHNjYWxlX3hfY29udGludW91cygNCiAgICBicmVha3MgPSBzZXEobWluKGxzX2V4cG9zZWRfc3RyZWFtJFB1YmxpY2F0aW9uX3llYXIsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgIG1heChsc19leHBvc2VkX3N0cmVhbSRQdWJsaWNhdGlvbl95ZWFyLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICBieSA9IDIpLA0KICAgIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgbGFicygNCiAgICB4ID0gIlB1YmxpY2F0aW9uIHllYXIiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiBvZiBzdHVkaWVzIiwNCiAgICB0aXRsZSA9ICJMaWZlIHN0YWdlIGV4cG9zZWQiKSArIA0KICBjdXN0b21fdGhlbWUgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCg0KIyMjIyBMaWZlIHN0YWdlIHRlc3RlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMgDQoNCmBgYHtyfQ0KIyBQcmVwYXJlIGRhdGEgZm9yIHN0cmVhbSBwbG90IChwcm9wb3J0aW9ucyBieSB5ZWFyIGFuZCBsaWZlIHN0YWdlKQ0KbHNfdGVzdGVkX3N0cmVhbSA8LSBkYXRhICU+JQ0KICBzZWxlY3QoUHVibGljYXRpb25feWVhciwgTGlmZV9zdGFnZV90ZXN0ZWQpICU+JQ0KICBtdXRhdGUoTGlmZV9zdGFnZV90ZXN0ZWQ9IHN0cnNwbGl0KExpZmVfc3RhZ2VfdGVzdGVkLCAiLCAiKSkgJT4lDQogIHVubmVzdChMaWZlX3N0YWdlX3Rlc3RlZCkgJT4lDQogIGdyb3VwX2J5KFB1YmxpY2F0aW9uX3llYXIsIExpZmVfc3RhZ2VfdGVzdGVkKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShQdWJsaWNhdGlvbl95ZWFyKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKG4pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoTGlmZV9zdGFnZV90ZXN0ZWQgPSBmYWN0b3IoDQogICAgTGlmZV9zdGFnZV90ZXN0ZWQsDQogICAgbGV2ZWxzID0gYygNCiAgICAgICJBZHVsdHMiLA0KICAgICAgIkxhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgIkVtYnJ5b3MiLCAgICAgICAgICAgICANCiAgICAgICJVbmNsZWFyIg0KICAgICkNCiAgKSkNCg0KIyBDcmVhdGUgcGxvdA0Kc3RyZWFtX2xzX3Rlc3RlZCA8LSBnZ3Bsb3QoZGF0YSA9IGxzX3Rlc3RlZF9zdHJlYW0sDQogICAgICAgYWVzKHggPSBQdWJsaWNhdGlvbl95ZWFyLA0KICAgICAgICAgICB5ID0gcHJvcG9ydGlvbiwNCiAgICAgICAgICAgZmlsbCA9IExpZmVfc3RhZ2VfdGVzdGVkKSkgKw0KICBnZW9tX3N0cmVhbSh0eXBlID0gInByb3BvcnRpb24iLCBhbHBoYSA9IDAuNikgKw0KICBnZW9tX3N0cmVhbV9sYWJlbCh0eXBlID0gInJpZGdlIiwgYWVzKGxhYmVsID0gTGlmZV9zdGFnZV90ZXN0ZWQpLCBzaXplID0gNykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxldHRlKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IHNlcShtaW4obHNfdGVzdGVkX3N0cmVhbSRQdWJsaWNhdGlvbl95ZWFyLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICBtYXgobHNfdGVzdGVkX3N0cmVhbSRQdWJsaWNhdGlvbl95ZWFyLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICBieSA9IDIpLA0KICAgIGV4cGFuZCA9IGMoMCwgMCkNCiAgKSArDQogIGxhYnMoDQogICAgeCA9ICJQdWJsaWNhdGlvbiB5ZWFyIiwNCiAgICB5ID0gIlByb3BvcnRpb24gb2Ygc3R1ZGllcyIsDQogICAgZmlsbCA9ICJMaWZlIHN0YWdlIHRlc3RlZCIsDQogICAgdGl0bGUgPSAiTGlmZSBzdGFnZSB0ZXN0ZWQiKSArIA0KICBjdXN0b21fdGhlbWUgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQpgYGANCg0KIyMjIyBDb21iaW5lIHBsb3RzDQpgYGB7ciwgZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSAyMH0NCiMgQ29tYmluZSBwbG90cw0Kc3RyZWFtX3Bsb3QgPC0gKHN0cmVhbV9sc19leHBvc2VkIHwgc3RyZWFtX2xzX3Rlc3RlZCkgKyANCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAiYSIsIHRhZ19zdWZmaXggPSAiLiIpICYgdGhlbWUocGxvdC50YWcgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDM1KSkNCg0Kc3RyZWFtX3Bsb3QNCmBgYA0KDQoNCiMjIyAqKlRyZW5kcyBhY3Jvc3Mgam91cm5hbHMqKiANCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KDQpgYGB7cn0NCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF9qb3VybmFsX2V4cCA8LSBzdW0obGlmZV9zdGFnZV9ieV9qb3VybmFsX2V4cCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3Rfam91cm5hbF9leHAgPC0gbGlmZV9zdGFnZV9ieV9qb3VybmFsX2V4cCAlPiUNCiAgZ3JvdXBfYnkoSm91cm5hbCkgJT4lDQogIG11dGF0ZShuX3RvdGFsID0gc3VtKG4pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgSm91cm5hbF9sYWJlbCA9IHJlb3JkZXIoSm91cm5hbCwgbl90b3RhbCksDQogICAgcGVyY2VudGFnZSA9IG4gLyBvdmVyYWxsX2pvdXJuYWxfZXhwICogMTAwICAjIGVhY2ggcm934oCZcyBwZXJjZW50YWdlIG9mIG92ZXJhbGwgc3R1ZGllcw0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIGpvdXJuYWwNCmxhYmVsX2RhdGFfZXhwIDwtIHBsb3Rfam91cm5hbF9leHAgJT4lDQogIGdyb3VwX2J5KEpvdXJuYWxfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQpqb3VybmFsX3Bsb3RfZXhwb3NlZCA8LSBnZ3Bsb3QocGxvdF9qb3VybmFsX2V4cCwgYWVzKHggPSBKb3VybmFsX2xhYmVsLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IGBMaWZlIHN0YWdlIGV4cG9zZWRgKSkgKw0KICBnZW9tX2NvbChhbHBoYSA9IDAuNiwgd2lkdGggPSAwLjgsIHNpemUgPSAwLjIsIGNvbG9yID0gImJsYWNrIikgKw0KICAjIExhYmVscyBmb3IgaW5kaXZpZHVhbCBzZWdtZW50cyAoaW5zaWRlIHRoZSBiYXJzKSwgb25seSBkaXNwbGF5IGlmIG4gPiAxNQ0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKG4gPj0gMTUsIG4sICIiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1LA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9cGFsZXR0ZSwgbmFtZSA9ICJMaWZlIHN0YWdlIGV4cG9zZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJKb3VybmFsIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJQZXJjZW50YWdlIG9mIHN0dWRpZXMgKCUpIiwNCiAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDEwKSwNCiAgICBleHBhbmQgPSBjKDAsIDEpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGN1c3RvbV90aGVtZSANCmBgYA0KDQoNCiMjIyMgTGlmZSBzdGFnZSB0ZXN0ZWQgZm9yIHBoeXNpb2xvZ2ljYWwgdHJhaXRzIA0KDQpgYGB7cn0NCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF9qb3VybmFsIDwtIHN1bShsaWZlX3N0YWdlX2J5X2pvdXJuYWwkbikNCg0KIyBEYXRhIHN1bW1hcnkgZm9yIHRoZSBwbG90DQpwbG90X2pvdXJuYWwgPC0gbGlmZV9zdGFnZV9ieV9qb3VybmFsICU+JQ0KICBncm91cF9ieShKb3VybmFsKSAlPiUNCiAgbXV0YXRlKG5fdG90YWwgPSBzdW0obikpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICBKb3VybmFsX2xhYmVsID0gcmVvcmRlcihKb3VybmFsLCBuX3RvdGFsKSwNCiAgICBwZXJjZW50YWdlID0gbiAvIG92ZXJhbGxfam91cm5hbCAqIDEwMA0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIGpvdXJuYWwNCmxhYmVsX2RhdGEgPC0gcGxvdF9qb3VybmFsICU+JQ0KICBncm91cF9ieShKb3VybmFsX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlcg0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0Kam91cm5hbF9wbG90X3Rlc3RlZCA8LSBnZ3Bsb3QocGxvdF9qb3VybmFsLCBhZXMoeCA9IEpvdXJuYWxfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgdGVzdGVkYCkpICsNCiAgZ2VvbV9jb2woYWxwaGEgPSAwLjYsIHdpZHRoID0gMC44LCBzaXplID0gMC4yLCBjb2xvciA9ICJibGFjayIpICsNCiAgIyBMYWJlbHMgZm9yIGluZGl2aWR1YWwgc2VnbWVudHMgKGluc2lkZSB0aGUgYmFycyksIG9ubHkgZGlzcGxheSBpZiBuID4gMTUNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShuID49IDE1LCBuLCAiIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNSwNCiAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxldHRlLCBuYW1lID0gIkxpZmUgc3RhZ2UgYXNzZXNzZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJKb3VybmFsIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJQZXJjZW50YWdlIG9mIHN0dWRpZXMgKCUpIiwNCiAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDEwKSwNCiAgICBleHBhbmQgPSBjKDAsIDEpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGN1c3RvbV90aGVtZSANCmBgYA0KDQojIyMjIENvbWJpbmUgcGxvdHMgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDIwfQ0KIyBDb21iaW5lIHBsb3RzDQpqb3VybmFsX3Bsb3QgPC0gKGpvdXJuYWxfcGxvdF9leHBvc2VkIHwgam91cm5hbF9wbG90X3Rlc3RlZCkgKyANCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAiYSIsIHRhZ19zdWZmaXggPSAiLiIpICYgdGhlbWUocGxvdC50YWcgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDM1KSkNCg0Kam91cm5hbF9wbG90DQpgYGANCg0KDQojIyMgKipDb21iaW5lIHBsb3RzKiogDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTUsIGZpZy53aWR0aCA9IDIwfQ0KDQpmaWd1cmVfMSA8LSAoc3RyZWFtX3Bsb3QgLyAgam91cm5hbF9wbG90KSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQpmaWd1cmVfMQ0KDQpnZ3NhdmUoZmlndXJlXzEsIGZpbGUgPSAiRmlnL2ZpZ3VyZV8xLnN2ZyIsIHdpZHRoPTMwLCBoZWlnaHQgPSAyMCwgZHBpID0gMTIwMCkNCmBgYA0KDQojIyAqKkZpZ3VyZSAyKiogDQoNCiMjIyAqKlRyZW5kcyBhY3Jvc3MgdHJhaXQgY2F0ZWdvcmllcyoqDQoNCiMjIyMgTGlmZSBzdGFnZSBleHBvc2VkIHRvIHRoZSBzdHJlc3NvciANCg0KYGBge3J9DQojIE92ZXJhbGwgc2FtcGxlIHNpemUNCm92ZXJhbGxfdHJhaXRfZXhwIDwtIHN1bShsaWZlX3N0YWdlX2J5X3RyYWl0X2V4cCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3RfdHJhaXRfZXhwIDwtIGxpZmVfc3RhZ2VfYnlfdHJhaXRfZXhwICU+JQ0KICBmaWx0ZXIoVHJhaXRfY2F0ZWdvcnkgIT0gIk90aGVyIikgJT4lICAjIFJlbW92ZSAiT3RoZXIiIGNhdGVnb3J5IGZvciBjbGFyaXR5DQogICMgUmVuYW1lIHRoZSB0cmFpdCBjYXRlZ29yaWVzDQogIG11dGF0ZShUcmFpdF9jYXRlZ29yeSA9IHJlY29kZShUcmFpdF9jYXRlZ29yeSwNCiAgICAgICAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UiID0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlL3ByZWZlcmVuY2UiLA0KICAgICAgICJJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5IiA9ICJJbW11bmUgZnVuY3Rpb24vc3RyZXNzIHBoeXNpb2xvZ3kiLA0KICAgICAgICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiA9ICJFbmVyZ2V0aWNzL21ldGFib2xpc20iDQogICkpICAlPiUNCiAgZ3JvdXBfYnkoVHJhaXRfY2F0ZWdvcnkpICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICB0cmFpdF9sYWJlbCA9IHJlb3JkZXIoVHJhaXRfY2F0ZWdvcnksIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90cmFpdF9leHAgKiAxMDANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciB0cmFpdA0KbGFiZWxfZGF0YV9leHAgPC0gcGxvdF90cmFpdF9leHAgJT4lDQogIGdyb3VwX2J5KHRyYWl0X2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQp0cmFpdF9wbG90X2V4cG9zZWQgPC0gZ2dwbG90KHBsb3RfdHJhaXRfZXhwLCBhZXMoeCA9IHRyYWl0X2xhYmVsLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IGBMaWZlIHN0YWdlIGV4cG9zZWRgKSkgKw0KICBnZW9tX2NvbChhbHBoYSA9IDAuNiwgd2lkdGggPSAwLjgsIHNpemUgPSAwLjIsIGNvbG9yID0gImJsYWNrIikgKw0KICAjIExhYmVscyBmb3IgaW5kaXZpZHVhbCBzZWdtZW50cyAoaW5zaWRlIHRoZSBiYXJzKTsgb25seSBkaXNwbGF5IGlmIG4gPiAxNQ0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKG4gPj0gMTUsIG4sICIiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1LA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUsIG5hbWUgPSAiTGlmZSBzdGFnZSBleHBvc2VkIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSAiVHJhaXQgY2F0ZWdvcnkiKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gIlBlcmNlbnRhZ2Ugb2Ygc3R1ZGllcyAoJSkiLA0KICAgIGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMTApLA0KICAgIGV4cGFuZCA9IGMoMCwgMSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgY3VzdG9tX3RoZW1lIA0KYGBgDQoNCg0KIyMjIyBMaWZlIHN0YWdlIHRlc3RlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMgDQoNCmBgYHtyfQ0KIyBPdmVyYWxsIHNhbXBsZSBzaXplDQpvdmVyYWxsX3RyYWl0IDwtIHN1bShsaWZlX3N0YWdlX2J5X3RyYWl0JG4pDQoNCiMgRGF0YSBzdW1tYXJ5IGZvciB0aGUgcGxvdA0KcGxvdF90cmFpdCA8LSBsaWZlX3N0YWdlX2J5X3RyYWl0ICU+JQ0KICBmaWx0ZXIoVHJhaXRfY2F0ZWdvcnkgIT0gIk90aGVyIikgJT4lICAjIFJlbW92ZSAiT3RoZXIiIGNhdGVnb3J5IGZvciBjbGFyaXR5DQogIG11dGF0ZShUcmFpdF9jYXRlZ29yeSA9IHJlY29kZShUcmFpdF9jYXRlZ29yeSwNCiAgICAgICAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UiID0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlL3ByZWZlcmVuY2UiLA0KICAgICAgICJJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5IiA9ICJJbW11bmUgZnVuY3Rpb24vc3RyZXNzIHBoeXNpb2xvZ3kiLA0KICAgICAgICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiA9ICJFbmVyZ2V0aWNzL21ldGFib2xpc20iDQogICkpICU+JQ0KICBtdXRhdGUoDQogICAgYExpZmUgc3RhZ2UgdGVzdGVkYCA9IGZhY3RvcigNCiAgICAgIGBMaWZlIHN0YWdlIHRlc3RlZGAsDQogICAgICBsZXZlbHMgPSBjKCJVbmNsZWFyIiwgIkVtYnJ5b3MiLCAiTGFydmFlIG9yIGp1dmVuaWxlcyIsICJBZHVsdHMiKQ0KICAgICkNCiAgKSAlPiUNCiAgZ3JvdXBfYnkoVHJhaXRfY2F0ZWdvcnkpICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICB0cmFpdF9sYWJlbCA9IHJlb3JkZXIoVHJhaXRfY2F0ZWdvcnksIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90cmFpdCAqIDEwMCAgDQogICkNCg0KIyBQcmVwYXJlIGEgc3VtbWFyeSBmb3IgdGhlIHRvdGFsIGNvdW50cyBwZXIgdHJhaXQNCmxhYmVsX2RhdGEgPC0gcGxvdF90cmFpdCAlPiUNCiAgZ3JvdXBfYnkodHJhaXRfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQp0cmFpdF9wbG90X3Rlc3RlZCA8LSBnZ3Bsb3QocGxvdF90cmFpdCwgYWVzKHggPSB0cmFpdF9sYWJlbCwgeSA9IHBlcmNlbnRhZ2UsIGZpbGwgPSBgTGlmZSBzdGFnZSB0ZXN0ZWRgKSkgKw0KICBnZW9tX2NvbChhbHBoYSA9IDAuNiwgd2lkdGggPSAwLjgsIHNpemUgPSAwLjIsIGNvbG9yID0gImJsYWNrIikgKw0KICAjIExhYmVscyBmb3IgaW5kaXZpZHVhbCBzZWdtZW50cyAoaW5zaWRlIHRoZSBiYXJzKTsgb25seSBkaXNwbGF5IGlmIG4gPiAxNQ0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKG4gPj0gMTUsIG4sICIiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1LA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUsIG5hbWUgPSAiTGlmZSBzdGFnZSBhc3Nlc3NlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIlRyYWl0IGNhdGVnb3J5IikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJQZXJjZW50YWdlIG9mIHN0dWRpZXMgKCUpIiwNCiAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDEwKSwNCiAgICBleHBhbmQgPSBjKDAsIDEpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGN1c3RvbV90aGVtZSANCmBgYA0KDQojIyMjIENvbWJpbmUgcGxvdHMgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTMsIGZpZy53aWR0aCA9IDIwfQ0KIyBDb21iaW5lIHBsb3RzDQp0cmFpdF9wbG90IDwtICh0cmFpdF9wbG90X2V4cG9zZWQgfCB0cmFpdF9wbG90X3Rlc3RlZCkgKyANCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAiYSIsIHRhZ19zdWZmaXggPSAiLiIpICYgdGhlbWUocGxvdC50YWcgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDM1KSkNCg0KdHJhaXRfcGxvdA0KYGBgDQoNCg0KIyMjICoqVHJlbmRzIGFjcm9zcyB0YXhvbm9taWMgZ3JvdXBzKioNCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KDQpgYGB7cn0NCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF90YXhhX2V4cCA8LSBzdW0obGlmZV9zdGFnZV9ieV90YXhhX2V4cCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3RfdGF4YV9leHAgPC0gbGlmZV9zdGFnZV9ieV90YXhhX2V4cCAlPiUNCiAgZ3JvdXBfYnkoVGF4b25vbWljX2dyb3VwKSAlPiUNCiAgbXV0YXRlKA0KICAgIG5fdG90YWwgPSBzdW0obikNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgVGF4YV9sYWJlbCA9IHJlb3JkZXIoVGF4b25vbWljX2dyb3VwLCBuX3RvdGFsKSwNCiAgICBwZXJjZW50YWdlID0gbiAvIG92ZXJhbGxfdGF4YV9leHAgKiAxMDAgIA0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIHRheG9ub21pYyBncm91cA0KbGFiZWxfZGF0YV9leHAgPC0gcGxvdF90YXhhX2V4cCAlPiUNCiAgZ3JvdXBfYnkoVGF4YV9sYWJlbCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICB0b3RhbF9wZXJjZW50YWdlID0gc3VtKHBlcmNlbnRhZ2UpLA0KICAgIHRvdGFsX2NvdW50ID0gZmlyc3Qobl90b3RhbCkNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgIyBPbmx5IGRpc3BsYXkgY291bnRzIGlmIDE1IG9yIGdyZWF0ZXINCiAgICBsYWJlbCA9IGlmZWxzZSh0b3RhbF9jb3VudCA+PSAxNSwgcGFzdGUwKCJuPSIsIHRvdGFsX2NvdW50KSwgTkEpDQogICkNCg0KIyBDcmVhdGUgdGhlIHBsb3QNCnRheGFfcGxvdF9leHBvc2VkIDwtIGdncGxvdChwbG90X3RheGFfZXhwLCBhZXMoeCA9IFRheGFfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgZXhwb3NlZGApKSArDQogIGdlb21fY29sKGFscGhhID0gMC42LCB3aWR0aCA9IDAuOCwgc2l6ZSA9IDAuMiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgTGFiZWxzIGZvciBpbmRpdmlkdWFsIHNlZ21lbnRzIChpbnNpZGUgdGhlIGJhcnMpLCBvbmx5IGRpc3BsYXkgaWYgbiA+IDE1DQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UobiA+PSAxNSwgbiwgIiIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsDQogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSwgbmFtZSA9ICJMaWZlIHN0YWdlIGV4cG9zZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJUYXhvbm9taWMgZ3JvdXAiKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gIlBlcmNlbnRhZ2Ugb2Ygc3R1ZGllcyAoJSkiLA0KICAgIGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMTApLA0KICAgIGV4cGFuZCA9IGMoMCwgMSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgY3VzdG9tX3RoZW1lIA0KDQpgYGANCg0KDQoNCiMjIyMgTGlmZSBzdGFnZSB0ZXN0ZWQgZm9yIHBoeXNpb2xvZ2ljYWwgdHJhaXRzIA0KDQpgYGB7cn0NCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF90YXhhIDwtIHN1bShsaWZlX3N0YWdlX2J5X3RheGEkbikNCg0KIyBEYXRhIHN1bW1hcnkgZm9yIHRoZSBwbG90DQpwbG90X3RheGEgPC0gbGlmZV9zdGFnZV9ieV90YXhhICU+JQ0KICBncm91cF9ieShUYXhvbm9taWNfZ3JvdXApICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICBUYXhhX2xhYmVsID0gcmVvcmRlcihUYXhvbm9taWNfZ3JvdXAsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90YXhhICogMTAwICANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciB0YXhvbm9taWMgZ3JvdXANCmxhYmVsX2RhdGEgPC0gcGxvdF90YXhhICU+JQ0KICBncm91cF9ieShUYXhhX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlcg0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0KdGF4YV9wbG90X3Rlc3RlZCA8LSBnZ3Bsb3QocGxvdF90YXhhLCBhZXMoeCA9IFRheGFfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgdGVzdGVkYCkpICsNCiAgZ2VvbV9jb2woYWxwaGEgPSAwLjYsIHdpZHRoID0gMC44LCBzaXplID0gMC4yLCBjb2xvciA9ICJibGFjayIpICsNCiAgIyBMYWJlbHMgZm9yIGluZGl2aWR1YWwgc2VnbWVudHMgKGluc2lkZSB0aGUgYmFycyksIG9ubHkgZGlzcGxheSBpZiBuID4gMTUNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShuID49IDE1LCBuLCAiIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNSwNCiAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKw0KDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUsIG5hbWUgPSAiTGlmZSBzdGFnZSBhc3Nlc3NlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIlRheG9ub21pYyBncm91cCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSAiUGVyY2VudGFnZSBvZiBzdHVkaWVzICglKSIsDQogICAgYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCksDQogICAgZXhwYW5kID0gYygwLCAxKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBjdXN0b21fdGhlbWUgDQpgYGANCg0KIyMjIyBDb21iaW5lIHBsb3RzIA0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDEzLCBmaWcud2lkdGggPSAyMH0NCiMgQ29tYmluZSBwbG90cw0KdGF4YV9wbG90IDwtICh0YXhhX3Bsb3RfZXhwb3NlZCB8IHRheGFfcGxvdF90ZXN0ZWQpICsgDQogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gImEiLCB0YWdfc3VmZml4ID0gIi4iKSAmIHRoZW1lKHBsb3QudGFnID0gZWxlbWVudF90ZXh0KHNpemUgPSAzNSkpDQoNCnRheGFfcGxvdA0KYGBgDQoNCg0KIyMjICoqVHJlbmRzIGFjcm9zcyBjbGltYXRpYyBzdHJlc3NvcnMqKg0KDQojIyMjIExpZmUgc3RhZ2UgZXhwb3NlZCB0byB0aGUgc3RyZXNzb3IgDQoNCmBgYHtyfQ0Kc3RyZXNzb3JfbGFiZWxfZXhwcnMgPC0gYygNCiAgIk90aGVyIiA9IGV4cHJlc3Npb24oIk90aGVyIiksDQogICJOb24tY2xpbWF0aWMgc3RyZXNzb3IiID0gZXhwcmVzc2lvbigiTm9uIn4iY2xpbWF0aWMifiJzdHJlc3NvciIpLA0KICAiSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiA9IGV4cHJlc3Npb24oIldhdGVyIn4iYXZhaWxhYmlsaXR5IiksDQogICJTYWxpbml0eSIgPSBleHByZXNzaW9uKCJTYWxpbml0eSIpLA0KICAicEgiID0gZXhwcmVzc2lvbigicEgiKSwNCiAgIk/igoIvQ0/igoIiID0gZXhwcmVzc2lvbihPWzJdKiIvIipDT1syXSksDQogICJUZW1wZXJhdHVyZSIgPSBleHByZXNzaW9uKCJUZW1wZXJhdHVyZSIpDQopDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF9zdHJlc3Nvcl9leHAgPC0gc3VtKGxpZmVfc3RhZ2VfYnlfc3RyZXNzb3JfZXhwJG4pDQoNCiMgRGF0YSBzdW1tYXJ5IGZvciB0aGUgcGxvdA0KcGxvdF9zdHJlc3Nvcl9leHAgPC0gbGlmZV9zdGFnZV9ieV9zdHJlc3Nvcl9leHAgJT4lDQogIGZpbHRlcihDbGltYXRlX2NoYW5nZV9zdHJlc3NvciAhPSAiT3RoZXIiICYgDQogICAgICAgICBDbGltYXRlX2NoYW5nZV9zdHJlc3NvciAhPSAiSW50ZXJhY3Rpb24gd2l0aCBub24tY2xpbWF0aWMgc3RyZXNzb3IiKSAlPiUgICMgVGFrZSBvdXQgc29tZSBjYXRlZ29yaWVzIGZvciBjbGFyaXR5DQogIGdyb3VwX2J5KENsaW1hdGVfY2hhbmdlX3N0cmVzc29yKSAlPiUNCiAgbXV0YXRlKA0KICAgIG5fdG90YWwgPSBzdW0obikNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgc3RyZXNzb3JfbGFiZWwgPSByZW9yZGVyKENsaW1hdGVfY2hhbmdlX3N0cmVzc29yLCBuX3RvdGFsKSwNCiAgICBwZXJjZW50YWdlID0gbiAvIG92ZXJhbGxfc3RyZXNzb3JfZXhwICogMTAwIA0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIHN0cmVzc29yDQpsYWJlbF9kYXRhX2V4cCA8LSBwbG90X3N0cmVzc29yX2V4cCAlPiUNCiAgZ3JvdXBfYnkoc3RyZXNzb3JfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQpzdHJlc3Nvcl9wbG90X2V4cG9zZWQgPC0gZ2dwbG90KHBsb3Rfc3RyZXNzb3JfZXhwLCBhZXMoeCA9IHN0cmVzc29yX2xhYmVsLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IGBMaWZlIHN0YWdlIGV4cG9zZWRgKSkgKw0KICBnZW9tX2NvbChhbHBoYSA9IDAuNiwgd2lkdGggPSAwLjgsIHNpemUgPSAwLjIsIGNvbG9yID0gImJsYWNrIikgKw0KICAjIExhYmVscyBmb3IgaW5kaXZpZHVhbCBzZWdtZW50cyAoaW5zaWRlIHRoZSBiYXJzKTsgb25seSBkaXNwbGF5IGlmIG4gPiAxNQ0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKG4gPj0gMTUsIG4sICIiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1LA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUsIG5hbWUgPSAiTGlmZSBzdGFnZSBleHBvc2VkIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSAiU3RyZXNzb3IgY2F0ZWdvcnkiLCBsYWJlbHMgPSBzdHJlc3Nvcl9sYWJlbF9leHBycykgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJQZXJjZW50YWdlIG9mIHN0dWRpZXMgKCUpIiwNCiAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDEwKSwNCiAgICBleHBhbmQgPSBjKDAsIDEpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGN1c3RvbV90aGVtZSANCmBgYA0KDQoNCg0KIyMjIyBMaWZlIHN0YWdlIHRlc3RlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMgDQoNCmBgYHtyfQ0Kc3RyZXNzb3JfbGFiZWxfZXhwcnMgPC0gYygNCiAgIk90aGVyIiA9IGV4cHJlc3Npb24oIk90aGVyIiksDQogICJOb24tY2xpbWF0aWMgc3RyZXNzb3IiID0gZXhwcmVzc2lvbigiTm9uIn4iY2xpbWF0aWMifiJzdHJlc3NvciIpLA0KICAiSHVtaWRpdHkvV2F0ZXIgYXZhaWxhYmlsaXR5IiA9IGV4cHJlc3Npb24oIldhdGVyIn4iYXZhaWxhYmlsaXR5IiksDQogICJTYWxpbml0eSIgPSBleHByZXNzaW9uKCJTYWxpbml0eSIpLA0KICAicEgiID0gZXhwcmVzc2lvbigicEgiKSwNCiAgIk/igoIvQ0/igoIiID0gZXhwcmVzc2lvbihPWzJdKiIvIipDT1syXSksDQogICJUZW1wZXJhdHVyZSIgPSBleHByZXNzaW9uKCJUZW1wZXJhdHVyZSIpDQopDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF9zdHJlc3NvciA8LSBzdW0obGlmZV9zdGFnZV9ieV9zdHJlc3NvciRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3Rfc3RyZXNzb3IgPC0gbGlmZV9zdGFnZV9ieV9zdHJlc3NvciAlPiUNCiAgZmlsdGVyKENsaW1hdGVfY2hhbmdlX3N0cmVzc29yICE9ICJPdGhlciIgJiANCiAgICAgICAgIENsaW1hdGVfY2hhbmdlX3N0cmVzc29yICE9ICJJbnRlcmFjdGlvbiB3aXRoIG5vbi1jbGltYXRpYyBzdHJlc3NvciIpICU+JSAgIyBUYWtlIG91dCBzb21lIGNhdGVnb3JpZXMgZm9yIGNsYXJpdHkNCiAgZ3JvdXBfYnkoQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IpICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICBzdHJlc3Nvcl9sYWJlbCA9IHJlb3JkZXIoQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF9zdHJlc3NvciAqIDEwMCAgDQogICkNCg0KIyBQcmVwYXJlIGEgc3VtbWFyeSBmb3IgdGhlIHRvdGFsIGNvdW50cyBwZXIgc3RyZXNzb3INCmxhYmVsX2RhdGEgPC0gcGxvdF9zdHJlc3NvciAlPiUNCiAgZ3JvdXBfYnkoc3RyZXNzb3JfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQpzdHJlc3Nvcl9wbG90X3Rlc3RlZCA8LSBnZ3Bsb3QocGxvdF9zdHJlc3NvciwgYWVzKHggPSBzdHJlc3Nvcl9sYWJlbCwgeSA9IHBlcmNlbnRhZ2UsIGZpbGwgPSBgTGlmZSBzdGFnZSB0ZXN0ZWRgKSkgKw0KICBnZW9tX2NvbChhbHBoYSA9IDAuNiwgd2lkdGggPSAwLjgsIHNpemUgPSAwLjIsIGNvbG9yID0gImJsYWNrIikgKw0KICAjIExhYmVscyBmb3IgaW5kaXZpZHVhbCBzZWdtZW50cyAoaW5zaWRlIHRoZSBiYXJzKTsgb25seSBkaXNwbGF5IGlmIG4gPiAxNQ0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKG4gPj0gMTUsIG4sICIiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwNCiAgICAgICAgICAgIHNpemUgPSA1LA0KICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhbGV0dGUsIG5hbWUgPSAiTGlmZSBzdGFnZSBhc3Nlc3NlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIlN0cmVzc29yIGNhdGVnb3J5IiwgbGFiZWxzID0gc3RyZXNzb3JfbGFiZWxfZXhwcnMpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSAiUGVyY2VudGFnZSBvZiBzdHVkaWVzICglKSIsDQogICAgYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCksDQogICAgZXhwYW5kID0gYygwLCAxKSkgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgY3VzdG9tX3RoZW1lIA0KYGBgDQoNCiMjIyMgQ29tYmluZSBwbG90cyANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAxMywgZmlnLndpZHRoID0gMjB9DQojIENvbWJpbmUgcGxvdHMNCnN0cmVzc29yX3Bsb3QgPC0gKHN0cmVzc29yX3Bsb3RfZXhwb3NlZCB8IHN0cmVzc29yX3Bsb3RfdGVzdGVkKSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQpzdHJlc3Nvcl9wbG90DQpgYGANCg0KDQojIyMgKipDb21iaW5lIHBsb3RzKiogDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTYsIGZpZy53aWR0aCA9IDIwfQ0KDQpmaWd1cmVfMiA8LSAodHJhaXRfcGxvdCAvICB0YXhhX3Bsb3QgLyBzdHJlc3Nvcl9wbG90KSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQpmaWd1cmVfMg0KDQpnZ3NhdmUoZmlndXJlXzIsIGZpbGUgPSAiRmlnL2ZpZ3VyZV8yLnN2ZyIsIHdpZHRoPTQwLCBoZWlnaHQgPSAzMCwgZHBpID0gMTIwMCwgbGltaXRzaXplID0gRkFMU0UpDQpgYGANCg0KDQojIyAqKkZpZ3VyZSAzKiogDQoNCkNvcmQgZGlhZ3JhbSB0byB2aXN1YWxpc2Ugc3R1ZGllcyB3aXRoIHNpbmdsZSB2cyBtdWx0aXBsZSBsaWZlIHN0YWdlcw0KDQpgYGB7cn0NCmNhdGVnb3JpZXMgPC0gYygiQWR1bHRzIiwgIkxhcnZhZSBvciBqdXZlbmlsZXMiLCAiRW1icnlvcyIpDQoNCiMgUGFyc2UgbGlmZSBzdGFnZXMNCmRhdGEgPC0gZGF0YSAlPiUgDQogIG11dGF0ZShsaWZlc3RhZ2VzID0gc3Ryc3BsaXQoTGlmZV9zdGFnZV90ZXN0ZWQsICIsXFxzKiIpICU+JSBtYXAodHJpbXdzKSkNCg0KIyBEdW1teSBsaXN0IHRvIHN0b3JlIG1hdHJpeA0KZHVtbXlfbGlzdCA8LSBkYXRhICU+JSANCiAgbXV0YXRlKGR1bW15ID0gbWFwKGxpZmVzdGFnZXMsIH4gYXMuaW50ZWdlcihjYXRlZ29yaWVzICVpbiUgLngpKSkgJT4lIA0KICBwdWxsKGR1bW15KSAlPiUgDQogIG1hcCh+IHNldE5hbWVzKC54LCBjYXRlZ29yaWVzKSkNCg0KIyBBZGQgbmFtZXMgdG8gZWFjaCBkdW1teSB2ZWN0b3INCmR1bW15X2xpc3QgPC0gbWFwKGR1bW15X2xpc3QsIH4gc2V0TmFtZXMoLngsIGNhdGVnb3JpZXMpKQ0KDQojIFN1bSB0aGUgb3V0ZXIgcHJvZHVjdHMgb2YgdGhlIGR1bW15IHZlY3RvcnMgdG8gZm9ybSBhIGNvLW9jY3VycmVuY2UgbWF0cml4Lg0KIyBFYWNoIHJlY29yZCBjb250cmlidXRlcyBhbiBvdXRlciBwcm9kdWN0OiBpZiBhIHJlY29yZCBoYXMgYm90aCAiQWR1bHRzIiBhbmQgIkVtYnJ5b3MiLCANCiMgdGhlbiBvdXRlcih2ZWMsIHZlYykgcmV0dXJucyBhIG1hdHJpeCB3aXRoIGEgMSBpbiB0aGF0IGNlbGwuDQpOZXRNYXRyaXhfbGlmZXN0YWdlIDwtIFJlZHVjZSgiKyIsIGxhcHBseShkdW1teV9saXN0LCBmdW5jdGlvbih2ZWMpIG91dGVyKHZlYywgdmVjKSkpDQoNCiMgU2VwYXJhdGUgY2FzZXMgd2hlcmUgdGhlcmUgaXMgYSBzaW5nbGUgdnMuIG11bHRpcGxlIGxpZmUgc3RhZ2VzDQpleGNsdXNpdmVfY291bnRzIDwtIHNhcHBseShjYXRlZ29yaWVzLCBmdW5jdGlvbihjYXQpIHsNCiAgc3VtKGxlbmd0aHMoZGF0YSRsaWZlc3RhZ2VzKSA9PSAxICYgdmFwcGx5KGRhdGEkbGlmZXN0YWdlcywgZnVuY3Rpb24oeCkgeFsxXSA9PSBjYXQsIGxvZ2ljYWwoMSkpKQ0KfSkNCg0KZGlhZyhOZXRNYXRyaXhfbGlmZXN0YWdlKSA8LSBleGNsdXNpdmVfY291bnRzICAgIyByZXBsYWNlIGRpYWdvbmFsDQpOZXRNYXRyaXhfbGlmZXN0YWdlW2xvd2VyLnRyaShOZXRNYXRyaXhfbGlmZXN0YWdlKV0gPC0gMCAgIyBSZW1vdmUgZHVwbGljYXRlZCBpbmZvcm1hdGlvbg0KDQojIENoZWNrIHRoZSBtYXRyaXgNCnByaW50KE5ldE1hdHJpeF9saWZlc3RhZ2UpDQoNCg0KIyBDcmVhdGUgdGhlIGNob3JkIGRpYWdyYW0NCiNwZGYoZmlsZSA9IkZpZy9maWd1cmVfMy5wZGYiLCB3aWR0aCA9IDgsIGhlaWdodCA9IDgsIHBvaW50c2l6ZSA9IDEwKQ0KcG5nKGZpbGUgPSJGaWcvZmlndXJlXzMucG5nIiwgcG9pbnRzaXplID0gNC41LCByZXMgPSAxMDAwLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSAxMCwgdW5pdCA9ICJjbSIsKQ0KDQpjaXJjb3MucGFyKGdhcC5hZnRlciA9IGMoMiwyLDIpKSAjIEFkanVzdCBzcGFjZSBiZXR3ZWVuIGNhdGVnb3JpZXMNCmZpZ3VyZV8zIDwtIGNob3JkRGlhZ3JhbShOZXRNYXRyaXhfbGlmZXN0YWdlLCANCiAgICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uVHJhY2sgPSAiZ3JpZCIsIA0KICAgICAgICAgICAgICAgICAgICAgIHByZUFsbG9jYXRlVHJhY2tzID0gMSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JpZC5jb2wgPSBwYWxldHRlLA0KICAgICAgICAgICAgICAgICAgICAgIHNlbGYubGluayA9IDEpICMgRG9uJ3QgZHVwbGljYXRlIGRhdGENCg0KIyBSZW1vdmUgdGhlIHNlY3RvciBuYW1lcyAobGFiZWxzKSBhbmQganVzdCBkaXNwbGF5IHRoZSBheGlzIChudW1iZXJzL3RpY2tzKQ0KY2lyY29zLnRyYWNrUGxvdFJlZ2lvbih0cmFjay5pbmRleCA9IDEsIHBhbmVsLmZ1biA9IGZ1bmN0aW9uKHgsIHkpIHsNCiAgeGxpbSA8LSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltIDwtIGdldC5jZWxsLm1ldGEuZGF0YSgieWxpbSIpDQogIHNlY3Rvci5uYW1lIDwtIGdldC5jZWxsLm1ldGEuZGF0YSgic2VjdG9yLmluZGV4IikNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC43NSwgbWFqb3IudGljay5sZW5ndGggPSAwLjIsIA0KICAgICAgICAgICAgICBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQoNCmZpZ3VyZV8zDQpkZXYub2ZmKCkNCmBgYA0KDQoNCiMgKipTdXBwbGVtZW50YXJ5IGZpZ3VyZXMqKg0KDQojIyAqKkZpZ3VyZSBTMSoqDQoNClRoaXMgZmlndXJlIHdhcyBnZW5lcmF0ZWQgaW4gcG93ZXJwb2ludC4NCg0KIyMgKipGaWd1cmUgUzIqKg0KDQpUaGlzIGZpZ3VyZSByZXByb2R1Y2VzIHRoZSBwYXR0ZXJucyBpbiBmaWd1cmUgMSwgYnV0IG9ubHkga2VlcGluZyBzdHVkaWVzIG1lYXN1cmluZyByZXNwb25zZXMgdG8gdGVtcGVyYXR1cmUgKGkuZS4sIHRoZSBtb3N0IGNvbW1vbiBjbGltYXRpYyBzdHJlc3NvcikNCg0KIyMjICoqVGVtcG9yYWwgdHJlbmRzKioNCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KYGBge3J9DQojIEZpbHRlciB0byBzdHVkaWVzIG9uIHRlbXBlcmF0dXJlIG9ubHkNCmRhdGFfdGVtcCA8LSBmaWx0ZXIoZGF0YSwgQ2xpbWF0ZV9jaGFuZ2Vfc3RyZXNzb3IgPT0gIlRlbXBlcmF0dXJlIikgIyA3NjUgc3R1ZGllcw0KDQojIFByZXBhcmUgZGF0YSBmb3Igc3RyZWFtIHBsb3QgKHByb3BvcnRpb25zIGJ5IHllYXIgYW5kIGxpZmUgc3RhZ2UpDQpsc19leHBvc2VkX3N0cmVhbV90ZW1wIDwtIGRhdGFfdGVtcCAlPiUNCiAgc2VsZWN0KFB1YmxpY2F0aW9uX3llYXIsIExpZmVfc3RhZ2VfZXhwb3NlZCkgJT4lDQogIG11dGF0ZShMaWZlX3N0YWdlX2V4cG9zZWQgPSBzdHJzcGxpdChMaWZlX3N0YWdlX2V4cG9zZWQsICIsICIpKSAlPiUNCiAgdW5uZXN0KExpZmVfc3RhZ2VfZXhwb3NlZCkgJT4lDQogIGdyb3VwX2J5KFB1YmxpY2F0aW9uX3llYXIsIExpZmVfc3RhZ2VfZXhwb3NlZCkgJT4lDQogIHN1bW1hcmlzZShuID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoUHVibGljYXRpb25feWVhcikgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShuKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKExpZmVfc3RhZ2VfZXhwb3NlZCA9IGZhY3RvcigNCiAgICBMaWZlX3N0YWdlX2V4cG9zZWQsDQogICAgbGV2ZWxzID0gYygNCiAgICAgICJBZHVsdHMiLA0KICAgICAgIkxhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgIkVtYnJ5b3MiLCAgICAgICAgICAgICANCiAgICAgICJNaXggKGJlZm9yZSBhbmQgYWZ0ZXIgaGF0Y2hpbmcpIiwNCiAgICAgICJNaXggKHN0cmljdGx5IGFmdGVyIGhhdGNoaW5nKSIsDQogICAgICAiVW5jbGVhciINCiAgICApDQogICkpDQoNCiMgQ3JlYXRlIHBsb3QNCnN0cmVhbV9sc19leHBvc2VkX3RlbXAgPC0gZ2dwbG90KGRhdGEgPSBsc19leHBvc2VkX3N0cmVhbV90ZW1wLA0KICAgICAgIGFlcyh4ID0gUHVibGljYXRpb25feWVhciwNCiAgICAgICAgICAgeSA9IHByb3BvcnRpb24sDQogICAgICAgICAgIGZpbGwgPSBMaWZlX3N0YWdlX2V4cG9zZWQpKSArDQogIGdlb21fc3RyZWFtKHR5cGUgPSAicHJvcG9ydGlvbiIsIGFscGhhID0gMC42KSArDQogIGdlb21fc3RyZWFtX2xhYmVsKHR5cGUgPSAicmlkZ2UiLCBhZXMobGFiZWwgPSBMaWZlX3N0YWdlX2V4cG9zZWQpLCBzaXplICA9IDcpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSkrICANCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxLCAwLjI1KSwNCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKA0KICAgIGJyZWFrcyA9IHNlcShtaW4obHNfZXhwb3NlZF9zdHJlYW0kUHVibGljYXRpb25feWVhciwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgbWF4KGxzX2V4cG9zZWRfc3RyZWFtJFB1YmxpY2F0aW9uX3llYXIsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgIGJ5ID0gMiksDQogICAgZXhwYW5kID0gYygwLCAwKSkgKw0KICBsYWJzKA0KICAgIHggPSAiUHVibGljYXRpb24geWVhciIsDQogICAgeSA9ICJQcm9wb3J0aW9uIG9mIHN0dWRpZXMiLA0KICAgIHRpdGxlID0gIkxpZmUgc3RhZ2UgZXhwb3NlZCIpICsgDQogIGN1c3RvbV90aGVtZSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KDQojIyMjIExpZmUgc3RhZ2UgdGVzdGVkIGZvciBwaHlzaW9sb2dpY2FsIHRyYWl0cyANCg0KYGBge3J9DQojIFByZXBhcmUgZGF0YSBmb3Igc3RyZWFtIHBsb3QgKHByb3BvcnRpb25zIGJ5IHllYXIgYW5kIGxpZmUgc3RhZ2UpDQpsc190ZXN0ZWRfc3RyZWFtX3RlbXAgPC0gZGF0YV90ZW1wICU+JQ0KICBzZWxlY3QoUHVibGljYXRpb25feWVhciwgTGlmZV9zdGFnZV90ZXN0ZWQpICU+JQ0KICBtdXRhdGUoTGlmZV9zdGFnZV90ZXN0ZWQ9IHN0cnNwbGl0KExpZmVfc3RhZ2VfdGVzdGVkLCAiLCAiKSkgJT4lDQogIHVubmVzdChMaWZlX3N0YWdlX3Rlc3RlZCkgJT4lDQogIGdyb3VwX2J5KFB1YmxpY2F0aW9uX3llYXIsIExpZmVfc3RhZ2VfdGVzdGVkKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShQdWJsaWNhdGlvbl95ZWFyKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKG4pKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoTGlmZV9zdGFnZV90ZXN0ZWQgPSBmYWN0b3IoDQogICAgTGlmZV9zdGFnZV90ZXN0ZWQsDQogICAgbGV2ZWxzID0gYygNCiAgICAgICJBZHVsdHMiLA0KICAgICAgIkxhcnZhZSBvciBqdXZlbmlsZXMiLA0KICAgICAgIkVtYnJ5b3MiLCAgICAgICAgICAgICANCiAgICAgICJVbmNsZWFyIg0KICAgICkNCiAgKSkNCg0KIyBDcmVhdGUgcGxvdA0Kc3RyZWFtX2xzX3Rlc3RlZF90ZW1wIDwtIGdncGxvdChkYXRhID0gbHNfdGVzdGVkX3N0cmVhbV90ZW1wLA0KICAgICAgIGFlcyh4ID0gUHVibGljYXRpb25feWVhciwNCiAgICAgICAgICAgeSA9IHByb3BvcnRpb24sDQogICAgICAgICAgIGZpbGwgPSBMaWZlX3N0YWdlX3Rlc3RlZCkpICsNCiAgZ2VvbV9zdHJlYW0odHlwZSA9ICJwcm9wb3J0aW9uIiwgYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9zdHJlYW1fbGFiZWwodHlwZSA9ICJyaWRnZSIsIGFlcyhsYWJlbCA9IExpZmVfc3RhZ2VfdGVzdGVkKSwgc2l6ZSA9IDcpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSkrDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArDQogIHNjYWxlX3hfY29udGludW91cygNCiAgICBicmVha3MgPSBzZXEobWluKGxzX3Rlc3RlZF9zdHJlYW0kUHVibGljYXRpb25feWVhciwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgbWF4KGxzX3Rlc3RlZF9zdHJlYW0kUHVibGljYXRpb25feWVhciwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgYnkgPSAyKSwNCiAgICBleHBhbmQgPSBjKDAsIDApDQogICkgKw0KICBsYWJzKA0KICAgIHggPSAiUHVibGljYXRpb24geWVhciIsDQogICAgeSA9ICJQcm9wb3J0aW9uIG9mIHN0dWRpZXMiLA0KICAgIGZpbGwgPSAiTGlmZSBzdGFnZSB0ZXN0ZWQiLA0KICAgIHRpdGxlID0gIkxpZmUgc3RhZ2UgdGVzdGVkIikgKyANCiAgY3VzdG9tX3RoZW1lICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KYGBgDQoNCiMjIyMgQ29tYmluZSBwbG90cw0KYGBge3IsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMjB9DQojIENvbWJpbmUgcGxvdHMNCnN0cmVhbV9wbG90X3RlbXAgPC0gKHN0cmVhbV9sc19leHBvc2VkX3RlbXAgfCBzdHJlYW1fbHNfdGVzdGVkX3RlbXApICsgDQogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gImEiLCB0YWdfc3VmZml4ID0gIi4iKSAmIHRoZW1lKHBsb3QudGFnID0gZWxlbWVudF90ZXh0KHNpemUgPSAzNSkpDQoNCnN0cmVhbV9wbG90X3RlbXANCmBgYA0KDQoNCiMjIyAqKlRyZW5kcyBhY3Jvc3Mgam91cm5hbHMqKiANCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIGRhdGEgc3VtbWFyeQ0KbGlmZV9zdGFnZV9ieV9qb3VybmFsX2V4cF90ZW1wIDwtIHNwbGl0X2FuZF9zdW1tYXJpc2UoZGF0YV90ZW1wLCAiSm91cm5hbCIpDQoNCmZsZXh0YWJsZShsaWZlX3N0YWdlX2J5X2pvdXJuYWxfZXhwX3RlbXApICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJMaWZlIHN0YWdlcyBleHBvc2VkIGFjcm9zcyBqb3VybmFscyIpICU+JSAgDQogIGJnKGJnID0gIndoaXRlIiwgcGFydCA9ICJhbGwiKSAlPiUgIA0KICBjb2xvcihjb2xvciA9ICJibGFjayIsIHBhcnQgPSAiYWxsIikNCg0KIyBPdmVyYWxsIHNhbXBsZSBzaXplDQpvdmVyYWxsX2pvdXJuYWxfZXhwX3RlbXAgPC0gc3VtKGxpZmVfc3RhZ2VfYnlfam91cm5hbF9leHBfdGVtcCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3Rfam91cm5hbF9leHBfdGVtcCA8LSBsaWZlX3N0YWdlX2J5X2pvdXJuYWxfZXhwX3RlbXAgJT4lDQogIGdyb3VwX2J5KEpvdXJuYWwpICU+JQ0KICBtdXRhdGUobl90b3RhbCA9IHN1bShuKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgIEpvdXJuYWxfbGFiZWwgPSByZW9yZGVyKEpvdXJuYWwsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF9qb3VybmFsX2V4cF90ZW1wICogMTAwICAjIGVhY2ggcm934oCZcyBwZXJjZW50YWdlIG9mIG92ZXJhbGwgc3R1ZGllcw0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIGpvdXJuYWwNCmxhYmVsX2RhdGFfZXhwX3RlbXAgPC0gcGxvdF9qb3VybmFsX2V4cF90ZW1wICU+JQ0KICBncm91cF9ieShKb3VybmFsX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlcg0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0Kam91cm5hbF9wbG90X2V4cG9zZWRfdGVtcCA8LSBnZ3Bsb3QocGxvdF9qb3VybmFsX2V4cF90ZW1wLCBhZXMoeCA9IEpvdXJuYWxfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgZXhwb3NlZGApKSArDQogIGdlb21fY29sKGFscGhhID0gMC42LCB3aWR0aCA9IDAuOCwgc2l6ZSA9IDAuMiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgTGFiZWxzIGZvciBpbmRpdmlkdWFsIHNlZ21lbnRzIChpbnNpZGUgdGhlIGJhcnMpLCBvbmx5IGRpc3BsYXkgaWYgbiA+IDE1DQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UobiA+PSAxNSwgbiwgIiIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsDQogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID1wYWxldHRlLCBuYW1lID0gIkxpZmUgc3RhZ2UgZXhwb3NlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIkpvdXJuYWwiKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gIlBlcmNlbnRhZ2Ugb2Ygc3R1ZGllcyAoJSkiLA0KICAgIGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMTApLA0KICAgIGV4cGFuZCA9IGMoMCwgMSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgY3VzdG9tX3RoZW1lIA0KYGBgDQoNCg0KIyMjIyBMaWZlIHN0YWdlIHRlc3RlZCBmb3IgcGh5c2lvbG9naWNhbCB0cmFpdHMgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgZGF0YSBzdW1tYXJ5DQpsaWZlX3N0YWdlX2J5X2pvdXJuYWxfdGVtcCA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlMihkYXRhX3RlbXAsICJKb3VybmFsIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfam91cm5hbF90ZW1wKSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgZXhwb3NlZCBhY3Jvc3Mgam91cm5hbHMiKSAlPiUgIA0KICBiZyhiZyA9ICJ3aGl0ZSIsIHBhcnQgPSAiYWxsIikgJT4lICANCiAgY29sb3IoY29sb3IgPSAiYmxhY2siLCBwYXJ0ID0gImFsbCIpDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF9qb3VybmFsX3RlbXAgPC0gc3VtKGxpZmVfc3RhZ2VfYnlfam91cm5hbF90ZW1wJG4pDQoNCiMgRGF0YSBzdW1tYXJ5IGZvciB0aGUgcGxvdA0KcGxvdF9qb3VybmFsX3RlbXAgPC0gbGlmZV9zdGFnZV9ieV9qb3VybmFsX3RlbXAgJT4lDQogIGdyb3VwX2J5KEpvdXJuYWwpICU+JQ0KICBtdXRhdGUobl90b3RhbCA9IHN1bShuKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgIEpvdXJuYWxfbGFiZWwgPSByZW9yZGVyKEpvdXJuYWwsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF9qb3VybmFsX3RlbXAgKiAxMDANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciBqb3VybmFsDQpsYWJlbF9kYXRhX3RlbXAgPC0gcGxvdF9qb3VybmFsX3RlbXAgJT4lDQogIGdyb3VwX2J5KEpvdXJuYWxfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQpqb3VybmFsX3Bsb3RfdGVzdGVkX3RlbXAgPC0gZ2dwbG90KHBsb3Rfam91cm5hbF90ZW1wLCBhZXMoeCA9IEpvdXJuYWxfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgdGVzdGVkYCkpICsNCiAgZ2VvbV9jb2woYWxwaGEgPSAwLjYsIHdpZHRoID0gMC44LCBzaXplID0gMC4yLCBjb2xvciA9ICJibGFjayIpICsNCiAgIyBMYWJlbHMgZm9yIGluZGl2aWR1YWwgc2VnbWVudHMgKGluc2lkZSB0aGUgYmFycyksIG9ubHkgZGlzcGxheSBpZiBuID4gMTUNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShuID49IDE1LCBuLCAiIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNSwNCiAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxldHRlLCBuYW1lID0gIkxpZmUgc3RhZ2UgYXNzZXNzZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJKb3VybmFsIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJQZXJjZW50YWdlIG9mIHN0dWRpZXMgKCUpIiwNCiAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDEwKSwNCiAgICBleHBhbmQgPSBjKDAsIDEpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGN1c3RvbV90aGVtZSANCmBgYA0KDQojIyMjIENvbWJpbmUgcGxvdHMgDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMTIsIGZpZy53aWR0aCA9IDIwfQ0KIyBDb21iaW5lIHBsb3RzDQpqb3VybmFsX3Bsb3RfdGVtcCA8LSAoam91cm5hbF9wbG90X2V4cG9zZWRfdGVtcCB8IGpvdXJuYWxfcGxvdF90ZXN0ZWRfdGVtcCkgKyANCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAiYSIsIHRhZ19zdWZmaXggPSAiLiIpICYgdGhlbWUocGxvdC50YWcgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDM1KSkNCg0Kam91cm5hbF9wbG90X3RlbXANCmBgYA0KDQoNCiMjIyAqKkNvbWJpbmUgcGxvdHMqKiANCg0KYGBge3IsIGZpZy5oZWlnaHQgPTE1LCBmaWcud2lkdGggPSAyMH0NCg0KZmlndXJlX1MyIDwtIChzdHJlYW1fcGxvdF90ZW1wIC8gIGpvdXJuYWxfcGxvdF90ZW1wKSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQpmaWd1cmVfUzINCg0KZ2dzYXZlKGZpZ3VyZV9TMiwgZmlsZSA9ICJGaWcvZmlndXJlX1MyLnN2ZyIsIHdpZHRoPTIwLCBoZWlnaHQgPSAxNSwgZHBpID0gMTIwMCkNCmBgYA0KDQojIyAqKkZpZ3VyZSBTMyoqDQoNClRoaXMgZmlndXJlIHJlcHJvZHVjZXMgdGhlIHBhdHRlcm5zIGluIGZpZ3VyZSAyLCBidXQgb25seSBrZWVwaW5nIHN0dWRpZXMgbWVhc3VyaW5nIHJlc3BvbnNlcyB0byB0ZW1wZXJhdHVyZSAoaS5lLiwgdGhlIG1vc3QgY29tbW9uIGNsaW1hdGljIHN0cmVzc29yKS4NCg0KIyMjICoqVHJlbmRzIGFjcm9zcyB0cmFpdCBjYXRlZ29yaWVzKioNCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIGRhdGEgc3VtbWFyeQ0KbGlmZV9zdGFnZV9ieV90cmFpdF9leHBfdGVtcCA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlKGRhdGFfdGVtcCwgIlRyYWl0X2NhdGVnb3J5IikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfdHJhaXRfZXhwX3RlbXApICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJMaWZlIHN0YWdlcyBleHBvc2VkIGFjcm9zcyB0cmFpdCBjYXRlZ29yaWVzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF90cmFpdF9leHBfdGVtcCA8LSBzdW0obGlmZV9zdGFnZV9ieV90cmFpdF9leHBfdGVtcCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3RfdHJhaXRfZXhwX3RlbXAgPC0gbGlmZV9zdGFnZV9ieV90cmFpdF9leHBfdGVtcCAlPiUNCiAgZmlsdGVyKFRyYWl0X2NhdGVnb3J5ICE9ICJPdGhlciIpICU+JSAgIyBSZW1vdmUgIk90aGVyIiBjYXRlZ29yeSBmb3IgY2xhcml0eQ0KICAjIFJlbmFtZSB0aGUgdHJhaXQgY2F0ZWdvcmllcw0KICBtdXRhdGUoVHJhaXRfY2F0ZWdvcnkgPSByZWNvZGUoVHJhaXRfY2F0ZWdvcnksDQogICAgICAgIkVudmlyb25tZW50YWwgdG9sZXJhbmNlIGFuZCBwcmVmZXJlbmNlIiA9ICJFbnZpcm9ubWVudGFsIHRvbGVyYW5jZS9wcmVmZXJlbmNlIiwNCiAgICAgICAiSW1tdW5lIGZ1bmN0aW9uIGFuZCBzdHJlc3MgcGh5c2lvbG9neSIgPSAiSW1tdW5lIGZ1bmN0aW9uL3N0cmVzcyBwaHlzaW9sb2d5IiwNCiAgICAgICAiRW5lcmdldGljcyBhbmQgbWV0YWJvbGlzbSIgPSAiRW5lcmdldGljcy9tZXRhYm9saXNtIg0KICApKSAgJT4lDQogIGdyb3VwX2J5KFRyYWl0X2NhdGVnb3J5KSAlPiUNCiAgbXV0YXRlKA0KICAgIG5fdG90YWwgPSBzdW0obikNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgdHJhaXRfbGFiZWwgPSByZW9yZGVyKFRyYWl0X2NhdGVnb3J5LCBuX3RvdGFsKSwNCiAgICBwZXJjZW50YWdlID0gbiAvIG92ZXJhbGxfdHJhaXRfZXhwX3RlbXAgKiAxMDANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciB0cmFpdA0KbGFiZWxfZGF0YV9leHBfdGVtcCA8LSBwbG90X3RyYWl0X2V4cF90ZW1wICU+JQ0KICBncm91cF9ieSh0cmFpdF9sYWJlbCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICB0b3RhbF9wZXJjZW50YWdlID0gc3VtKHBlcmNlbnRhZ2UpLA0KICAgIHRvdGFsX2NvdW50ID0gZmlyc3Qobl90b3RhbCkNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUoDQogICAgIyBPbmx5IGRpc3BsYXkgY291bnRzIGlmIDE1IG9yIGdyZWF0ZQ0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0KdHJhaXRfcGxvdF9leHBvc2VkX3RlbXAgPC0gZ2dwbG90KHBsb3RfdHJhaXRfZXhwX3RlbXAsIGFlcyh4ID0gdHJhaXRfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgZXhwb3NlZGApKSArDQogIGdlb21fY29sKGFscGhhID0gMC42LCB3aWR0aCA9IDAuOCwgc2l6ZSA9IDAuMiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgTGFiZWxzIGZvciBpbmRpdmlkdWFsIHNlZ21lbnRzIChpbnNpZGUgdGhlIGJhcnMpOyBvbmx5IGRpc3BsYXkgaWYgbiA+IDE1DQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UobiA+PSAxNSwgbiwgIiIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsDQogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSwgbmFtZSA9ICJMaWZlIHN0YWdlIGV4cG9zZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJUcmFpdCBjYXRlZ29yeSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSAiUGVyY2VudGFnZSBvZiBzdHVkaWVzICglKSIsDQogICAgYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCksDQogICAgZXhwYW5kID0gYygwLCAxKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBjdXN0b21fdGhlbWUgDQpgYGANCg0KDQojIyMjIExpZmUgc3RhZ2UgdGVzdGVkIGZvciBwaHlzaW9sb2dpY2FsIHRyYWl0cyANCg0KYGBge3J9DQojIENhbGN1bGF0ZSBkYXRhIHN1bW1hcnkNCmxpZmVfc3RhZ2VfYnlfdHJhaXRfdGVtcCA8LSBzcGxpdF9hbmRfc3VtbWFyaXNlMihkYXRhX3RlbXAsICJUcmFpdF9jYXRlZ29yeSIpDQoNCmZsZXh0YWJsZShsaWZlX3N0YWdlX2J5X3RyYWl0X3RlbXApICU+JQ0KICBhdXRvZml0KCkgJT4lDQogIHNldF9jYXB0aW9uKCJMaWZlIHN0YWdlcyB0ZXN0ZWQgYWNyb3NzIHRyYWl0IGNhdGVnb3JpZXMiKSAlPiUgIA0KICBiZyhiZyA9ICJ3aGl0ZSIsIHBhcnQgPSAiYWxsIikgJT4lICANCiAgY29sb3IoY29sb3IgPSAiYmxhY2siLCBwYXJ0ID0gImFsbCIpDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF90cmFpdF90ZW1wIDwtIHN1bShsaWZlX3N0YWdlX2J5X3RyYWl0X3RlbXAkbikNCg0KIyBEYXRhIHN1bW1hcnkgZm9yIHRoZSBwbG90DQpwbG90X3RyYWl0X3RlbXAgPC0gbGlmZV9zdGFnZV9ieV90cmFpdF90ZW1wICU+JQ0KICBmaWx0ZXIoVHJhaXRfY2F0ZWdvcnkgIT0gIk90aGVyIikgJT4lICAjIFJlbW92ZSAiT3RoZXIiIGNhdGVnb3J5IGZvciBjbGFyaXR5DQogIG11dGF0ZShUcmFpdF9jYXRlZ29yeSA9IHJlY29kZShUcmFpdF9jYXRlZ29yeSwNCiAgICAgICAiRW52aXJvbm1lbnRhbCB0b2xlcmFuY2UgYW5kIHByZWZlcmVuY2UiID0gIkVudmlyb25tZW50YWwgdG9sZXJhbmNlL3ByZWZlcmVuY2UiLA0KICAgICAgICJJbW11bmUgZnVuY3Rpb24gYW5kIHN0cmVzcyBwaHlzaW9sb2d5IiA9ICJJbW11bmUgZnVuY3Rpb24vc3RyZXNzIHBoeXNpb2xvZ3kiLA0KICAgICAgICJFbmVyZ2V0aWNzIGFuZCBtZXRhYm9saXNtIiA9ICJFbmVyZ2V0aWNzL21ldGFib2xpc20iDQogICkpICU+JQ0KICBtdXRhdGUoDQogICAgYExpZmUgc3RhZ2UgdGVzdGVkYCA9IGZhY3RvcigNCiAgICAgIGBMaWZlIHN0YWdlIHRlc3RlZGAsDQogICAgICBsZXZlbHMgPSBjKCJVbmNsZWFyIiwgIkVtYnJ5b3MiLCAiTGFydmFlIG9yIGp1dmVuaWxlcyIsICJBZHVsdHMiKQ0KICAgICkNCiAgKSAlPiUNCiAgZ3JvdXBfYnkoVHJhaXRfY2F0ZWdvcnkpICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICB0cmFpdF9sYWJlbCA9IHJlb3JkZXIoVHJhaXRfY2F0ZWdvcnksIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90cmFpdF90ZW1wICogMTAwICANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciB0cmFpdA0KbGFiZWxfZGF0YV90ZW1wIDwtIHBsb3RfdHJhaXRfdGVtcCAlPiUNCiAgZ3JvdXBfYnkodHJhaXRfbGFiZWwpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfcGVyY2VudGFnZSA9IHN1bShwZXJjZW50YWdlKSwNCiAgICB0b3RhbF9jb3VudCA9IGZpcnN0KG5fdG90YWwpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKA0KICAgICMgT25seSBkaXNwbGF5IGNvdW50cyBpZiAxNSBvciBncmVhdGVyDQogICAgbGFiZWwgPSBpZmVsc2UodG90YWxfY291bnQgPj0gMTUsIHBhc3RlMCgibj0iLCB0b3RhbF9jb3VudCksIE5BKQ0KICApDQoNCiMgQ3JlYXRlIHRoZSBwbG90DQp0cmFpdF9wbG90X3Rlc3RlZF90ZW1wIDwtIGdncGxvdChwbG90X3RyYWl0X3RlbXAsIGFlcyh4ID0gdHJhaXRfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgdGVzdGVkYCkpICsNCiAgZ2VvbV9jb2woYWxwaGEgPSAwLjYsIHdpZHRoID0gMC44LCBzaXplID0gMC4yLCBjb2xvciA9ICJibGFjayIpICsNCiAgIyBMYWJlbHMgZm9yIGluZGl2aWR1YWwgc2VnbWVudHMgKGluc2lkZSB0aGUgYmFycyk7IG9ubHkgZGlzcGxheSBpZiBuID4gMTUNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShuID49IDE1LCBuLCAiIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksDQogICAgICAgICAgICBzaXplID0gNSwNCiAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxldHRlLCBuYW1lID0gIkxpZmUgc3RhZ2UgYXNzZXNzZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJUcmFpdCBjYXRlZ29yeSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIG5hbWUgPSAiUGVyY2VudGFnZSBvZiBzdHVkaWVzICglKSIsDQogICAgYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCksDQogICAgZXhwYW5kID0gYygwLCAxKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBjdXN0b21fdGhlbWUgDQpgYGANCg0KIyMjIyBDb21iaW5lIHBsb3RzIA0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDEzLCBmaWcud2lkdGggPSAyMH0NCiMgQ29tYmluZSBwbG90cw0KdHJhaXRfcGxvdF90ZW1wIDwtICh0cmFpdF9wbG90X2V4cG9zZWRfdGVtcCB8IHRyYWl0X3Bsb3RfdGVzdGVkX3RlbXApICsgDQogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gImEiLCB0YWdfc3VmZml4ID0gIi4iKSAmIHRoZW1lKHBsb3QudGFnID0gZWxlbWVudF90ZXh0KHNpemUgPSAzNSkpDQoNCnRyYWl0X3Bsb3RfdGVtcA0KYGBgDQoNCg0KIyMjICoqVHJlbmRzIGFjcm9zcyB0YXhvbm9taWMgZ3JvdXBzKioNCg0KIyMjIyBMaWZlIHN0YWdlIGV4cG9zZWQgdG8gdGhlIHN0cmVzc29yIA0KDQpgYGB7cn0NCiMgQ3JlYXRlIGRhdGEgc3VtbWFyeQ0KbGlmZV9zdGFnZV9ieV90YXhhX2V4cF90ZW1wIDwtIHNwbGl0X2FuZF9zdW1tYXJpc2UoZGF0YV90ZW1wLCAiVGF4b25vbWljX2dyb3VwIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfdGF4YV9leHBfdGVtcCkgJT4lDQogIGF1dG9maXQoKSAlPiUNCiAgc2V0X2NhcHRpb24oIkxpZmUgc3RhZ2VzIGV4cG9zZWQgYWNyb3NzIHRheG9ub21pYyBncm91cHMiKSAlPiUgIA0KICBiZyhiZyA9ICJ3aGl0ZSIsIHBhcnQgPSAiYWxsIikgJT4lICANCiAgY29sb3IoY29sb3IgPSAiYmxhY2siLCBwYXJ0ID0gImFsbCIpDQoNCiMgT3ZlcmFsbCBzYW1wbGUgc2l6ZQ0Kb3ZlcmFsbF90YXhhX2V4cF90ZW1wIDwtIHN1bShsaWZlX3N0YWdlX2J5X3RheGFfZXhwX3RlbXAkbikNCg0KIyBEYXRhIHN1bW1hcnkgZm9yIHRoZSBwbG90DQpwbG90X3RheGFfZXhwX3RlbXAgPC0gbGlmZV9zdGFnZV9ieV90YXhhX2V4cF90ZW1wICU+JQ0KICBncm91cF9ieShUYXhvbm9taWNfZ3JvdXApICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICBUYXhhX2xhYmVsID0gcmVvcmRlcihUYXhvbm9taWNfZ3JvdXAsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90YXhhX2V4cF90ZW1wICogMTAwICANCiAgKQ0KDQojIFByZXBhcmUgYSBzdW1tYXJ5IGZvciB0aGUgdG90YWwgY291bnRzIHBlciB0YXhvbm9taWMgZ3JvdXANCmxhYmVsX2RhdGFfZXhwX3RlbXAgPC0gcGxvdF90YXhhX2V4cF90ZW1wICU+JQ0KICBncm91cF9ieShUYXhhX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlcg0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0KdGF4YV9wbG90X2V4cG9zZWRfdGVtcCA8LSBnZ3Bsb3QocGxvdF90YXhhX2V4cF90ZW1wLCBhZXMoeCA9IFRheGFfbGFiZWwsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gYExpZmUgc3RhZ2UgZXhwb3NlZGApKSArDQogIGdlb21fY29sKGFscGhhID0gMC42LCB3aWR0aCA9IDAuOCwgc2l6ZSA9IDAuMiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgTGFiZWxzIGZvciBpbmRpdmlkdWFsIHNlZ21lbnRzIChpbnNpZGUgdGhlIGJhcnMpLCBvbmx5IGRpc3BsYXkgaWYgbiA+IDE1DQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UobiA+PSAxNSwgbiwgIiIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsDQogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcGFsZXR0ZSwgbmFtZSA9ICJMaWZlIHN0YWdlIGV4cG9zZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJUYXhvbm9taWMgZ3JvdXAiKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gIlBlcmNlbnRhZ2Ugb2Ygc3R1ZGllcyAoJSkiLA0KICAgIGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMTApLA0KICAgIGV4cGFuZCA9IGMoMCwgMSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgY3VzdG9tX3RoZW1lIA0KDQpgYGANCg0KDQoNCiMjIyMgTGlmZSBzdGFnZSB0ZXN0ZWQgZm9yIHBoeXNpb2xvZ2ljYWwgdHJhaXRzIA0KDQpgYGB7cn0NCiMgQ3JlYXRlIGRhdGEgc3VtbWFyeQ0KbGlmZV9zdGFnZV9ieV90YXhhX3RlbXAgPC0gc3BsaXRfYW5kX3N1bW1hcmlzZTIoZGF0YV90ZW1wLCAiVGF4b25vbWljX2dyb3VwIikNCg0KZmxleHRhYmxlKGxpZmVfc3RhZ2VfYnlfdGF4YV90ZW1wKSAlPiUNCiAgYXV0b2ZpdCgpICU+JQ0KICBzZXRfY2FwdGlvbigiTGlmZSBzdGFnZXMgdGVzdGVkIGFjcm9zcyB0YXhvbm9taWMgZ3JvdXBzIikgJT4lICANCiAgYmcoYmcgPSAid2hpdGUiLCBwYXJ0ID0gImFsbCIpICU+JSAgDQogIGNvbG9yKGNvbG9yID0gImJsYWNrIiwgcGFydCA9ICJhbGwiKQ0KDQojIE92ZXJhbGwgc2FtcGxlIHNpemUNCm92ZXJhbGxfdGF4YV90ZW1wIDwtIHN1bShsaWZlX3N0YWdlX2J5X3RheGFfdGVtcCRuKQ0KDQojIERhdGEgc3VtbWFyeSBmb3IgdGhlIHBsb3QNCnBsb3RfdGF4YV90ZW1wIDwtIGxpZmVfc3RhZ2VfYnlfdGF4YV90ZW1wICU+JQ0KICBncm91cF9ieShUYXhvbm9taWNfZ3JvdXApICU+JQ0KICBtdXRhdGUoDQogICAgbl90b3RhbCA9IHN1bShuKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICBUYXhhX2xhYmVsID0gcmVvcmRlcihUYXhvbm9taWNfZ3JvdXAsIG5fdG90YWwpLA0KICAgIHBlcmNlbnRhZ2UgPSBuIC8gb3ZlcmFsbF90YXhhX3RlbXAgKiAxMDAgIA0KICApDQoNCiMgUHJlcGFyZSBhIHN1bW1hcnkgZm9yIHRoZSB0b3RhbCBjb3VudHMgcGVyIHRheG9ub21pYyBncm91cA0KbGFiZWxfZGF0YV90ZW1wIDwtIHBsb3RfdGF4YV90ZW1wICU+JQ0KICBncm91cF9ieShUYXhhX2xhYmVsKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIHRvdGFsX3BlcmNlbnRhZ2UgPSBzdW0ocGVyY2VudGFnZSksDQogICAgdG90YWxfY291bnQgPSBmaXJzdChuX3RvdGFsKQ0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSgNCiAgICAjIE9ubHkgZGlzcGxheSBjb3VudHMgaWYgMTUgb3IgZ3JlYXRlcg0KICAgIGxhYmVsID0gaWZlbHNlKHRvdGFsX2NvdW50ID49IDE1LCBwYXN0ZTAoIm49IiwgdG90YWxfY291bnQpLCBOQSkNCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdA0KdGF4YV9wbG90X3Rlc3RlZF90ZW1wIDwtIGdncGxvdChwbG90X3RheGFfdGVtcCwgYWVzKHggPSBUYXhhX2xhYmVsLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IGBMaWZlIHN0YWdlIHRlc3RlZGApKSArDQogIGdlb21fY29sKGFscGhhID0gMC42LCB3aWR0aCA9IDAuOCwgc2l6ZSA9IDAuMiwgY29sb3IgPSAiYmxhY2siKSArDQogICMgTGFiZWxzIGZvciBpbmRpdmlkdWFsIHNlZ21lbnRzIChpbnNpZGUgdGhlIGJhcnMpLCBvbmx5IGRpc3BsYXkgaWYgbiA+IDE1DQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UobiA+PSAxNSwgbiwgIiIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgc2l6ZSA9IDUsDQogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCg0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYWxldHRlLCBuYW1lID0gIkxpZmUgc3RhZ2UgYXNzZXNzZWQiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJUYXhvbm9taWMgZ3JvdXAiKSArDQogIHNjYWxlX3lfY29udGludW91cygNCiAgICBuYW1lID0gIlBlcmNlbnRhZ2Ugb2Ygc3R1ZGllcyAoJSkiLA0KICAgIGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMTApLA0KICAgIGV4cGFuZCA9IGMoMCwgMSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgY3VzdG9tX3RoZW1lIA0KYGBgDQoNCiMjIyMgQ29tYmluZSBwbG90cyANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAxMywgZmlnLndpZHRoID0gMjB9DQojIENvbWJpbmUgcGxvdHMNCnRheGFfcGxvdF90ZW1wIDwtICh0YXhhX3Bsb3RfZXhwb3NlZF90ZW1wIHwgdGF4YV9wbG90X3Rlc3RlZF90ZW1wKSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQp0YXhhX3Bsb3RfdGVtcA0KYGBgDQoNCiMjIyAqKkNvbWJpbmUgcGxvdHMqKiANCg0KYGBge3IsIGZpZy5oZWlnaHQgPSAxNSwgZmlnLndpZHRoID0gMjB9DQoNCmZpZ3VyZV9TMyA8LSAodHJhaXRfcGxvdF90ZW1wIC8gIHRheGFfcGxvdF90ZW1wKSArIA0KICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJhIiwgdGFnX3N1ZmZpeCA9ICIuIikgJiB0aGVtZShwbG90LnRhZyA9IGVsZW1lbnRfdGV4dChzaXplID0gMzUpKQ0KDQpmaWd1cmVfUzMNCg0KZ2dzYXZlKGZpZ3VyZV9TMywgZmlsZSA9ICJGaWcvZmlndXJlX1MzLnN2ZyIsIHdpZHRoPTM1LCBoZWlnaHQgPSAyMCwgZHBpID0gMTIwMCwgbGltaXRzaXplID0gRkFMU0UpDQpgYGANCg0KIyMgKipGaWd1cmUgUzQqKiANCg0KVGhpcyBmaWd1cmUgcmVwcm9kdWNlcyB0aGUgcGF0dGVybnMgaW4gZmlndXJlIDMsIGJ1dCBvbmx5IGtlZXBpbmcgc3R1ZGllcyBtZWFzdXJpbmcgcmVzcG9uc2VzIHRvIHRlbXBlcmF0dXJlIChpLmUuLCB0aGUgbW9zdCBjb21tb24gY2xpbWF0aWMgc3RyZXNzb3IpLg0KDQpgYGB7cn0NCmNhdGVnb3JpZXMgPC0gYygiQWR1bHRzIiwgIkxhcnZhZSBvciBqdXZlbmlsZXMiLCAiRW1icnlvcyIpDQoNCiMgUGFyc2UgbGlmZSBzdGFnZXMNCmRhdGFfdGVtcCA8LSBkYXRhX3RlbXAgJT4lIA0KICBtdXRhdGUobGlmZXN0YWdlcyA9IHN0cnNwbGl0KExpZmVfc3RhZ2VfdGVzdGVkLCAiLFxccyoiKSAlPiUgbWFwKHRyaW13cykpDQoNCiMgRHVtbXkgbGlzdCB0byBzdG9yZSBtYXRyaXgNCmR1bW15X2xpc3RfdGVtcCA8LSBkYXRhX3RlbXAgJT4lIA0KICBtdXRhdGUoZHVtbXkgPSBtYXAobGlmZXN0YWdlcywgfiBhcy5pbnRlZ2VyKGNhdGVnb3JpZXMgJWluJSAueCkpKSAlPiUgDQogIHB1bGwoZHVtbXkpICU+JSANCiAgbWFwKH4gc2V0TmFtZXMoLngsIGNhdGVnb3JpZXMpKQ0KDQojIEFkZCBuYW1lcyB0byBlYWNoIGR1bW15IHZlY3Rvcg0KZHVtbXlfbGlzdF90ZW1wIDwtIG1hcChkdW1teV9saXN0X3RlbXAsIH4gc2V0TmFtZXMoLngsIGNhdGVnb3JpZXMpKQ0KDQojIFN1bSB0aGUgb3V0ZXIgcHJvZHVjdHMgb2YgdGhlIGR1bW15IHZlY3RvcnMgdG8gZm9ybSBhIGNvLW9jY3VycmVuY2UgbWF0cml4Lg0KIyBFYWNoIHJlY29yZCBjb250cmlidXRlcyBhbiBvdXRlciBwcm9kdWN0OiBpZiBhIHJlY29yZCBoYXMgYm90aCAiQWR1bHRzIiBhbmQgIkVtYnJ5b3MiLCANCiMgdGhlbiBvdXRlcih2ZWMsIHZlYykgcmV0dXJucyBhIG1hdHJpeCB3aXRoIGEgMSBpbiB0aGF0IGNlbGwuDQpOZXRNYXRyaXhfbGlmZXN0YWdlX3RlbXAgPC0gUmVkdWNlKCIrIiwgbGFwcGx5KGR1bW15X2xpc3RfdGVtcCwgZnVuY3Rpb24odmVjKSBvdXRlcih2ZWMsIHZlYykpKQ0KDQojIFNlcGFyYXRlIGNhc2VzIHdoZXJlIHRoZXJlIGlzIGEgc2luZ2xlIHZzLiBtdWx0aXBsZSBsaWZlIHN0YWdlcw0KZXhjbHVzaXZlX2NvdW50c190ZW1wIDwtIHNhcHBseShjYXRlZ29yaWVzLCBmdW5jdGlvbihjYXQpIHsNCiAgc3VtKGxlbmd0aHMoZGF0YV90ZW1wJGxpZmVzdGFnZXMpID09IDEgJiB2YXBwbHkoZGF0YV90ZW1wJGxpZmVzdGFnZXMsIGZ1bmN0aW9uKHgpIHhbMV0gPT0gY2F0LCBsb2dpY2FsKDEpKSkNCn0pDQoNCmRpYWcoTmV0TWF0cml4X2xpZmVzdGFnZV90ZW1wKSA8LSBleGNsdXNpdmVfY291bnRzX3RlbXAgICAjIHJlcGxhY2UgZGlhZ29uYWwNCk5ldE1hdHJpeF9saWZlc3RhZ2VfdGVtcFtsb3dlci50cmkoTmV0TWF0cml4X2xpZmVzdGFnZV90ZW1wKV0gPC0gMCAgIyBSZW1vdmUgZHVwbGljYXRlZCBpbmZvcm1hdGlvbg0KDQojIENoZWNrIHRoZSBtYXRyaXgNCnByaW50KE5ldE1hdHJpeF9saWZlc3RhZ2VfdGVtcCkNCg0KIyBDcmVhdGUgdGhlIGNob3JkIGRpYWdyYW0NCnBuZyhmaWxlID0iRmlnL2ZpZ3VyZV9TNC5wbmciLCBwb2ludHNpemUgPSA0LjUsIHJlcyA9IDEwMDAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDEwLCB1bml0ID0gImNtIiwpDQoNCmNpcmNvcy5wYXIoZ2FwLmFmdGVyID0gYygyLDIsMikpICMgQWRqdXN0IHNwYWNlIGJldHdlZW4gY2F0ZWdvcmllcw0KZmlndXJlX1M0IDwtIGNob3JkRGlhZ3JhbShOZXRNYXRyaXhfbGlmZXN0YWdlX3RlbXAsIA0KICAgICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgDQogICAgICAgICAgICAgICAgICAgICAgcHJlQWxsb2NhdGVUcmFja3MgPSAxLCANCiAgICAgICAgICAgICAgICAgICAgICBncmlkLmNvbCA9IHBhbGV0dGUsDQogICAgICAgICAgICAgICAgICAgICAgc2VsZi5saW5rID0gMSkgIyBEb24ndCBkdXBsaWNhdGUgZGF0YQ0KDQojIFJlbW92ZSB0aGUgc2VjdG9yIG5hbWVzIChsYWJlbHMpIGFuZCBqdXN0IGRpc3BsYXkgdGhlIGF4aXMgKG51bWJlcnMvdGlja3MpDQpjaXJjb3MudHJhY2tQbG90UmVnaW9uKHRyYWNrLmluZGV4ID0gMSwgcGFuZWwuZnVuID0gZnVuY3Rpb24oeCwgeSkgew0KICB4bGltIDwtIGdldC5jZWxsLm1ldGEuZGF0YSgieGxpbSIpDQogIHlsaW0gPC0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPC0gZ2V0LmNlbGwubWV0YS5kYXRhKCJzZWN0b3IuaW5kZXgiKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjc1LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgDQogICAgICAgICAgICAgIHNlY3Rvci5pbmRleCA9IHNlY3Rvci5uYW1lLCB0cmFjay5pbmRleCA9IDIpDQp9LCBiZy5ib3JkZXIgPSBOQSkNCg0KZmlndXJlX1M0DQpkZXYub2ZmKCkNCg0KYGBgDQoNCg0KIyBQYWNrYWdlIHZlcnNpb25zDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0KDQo=